I'm trying Project Panama (foreign function interface) of Java 19 with following code to read the current directory on Windows 10 (as a simple example). This is the begin of my code:
final Linker linker = Linker.nativeLinker();
final SymbolLookup linkerLookup = linker.defaultLookup();
final SymbolLookup systemLookup = SymbolLookup.loaderLookup();
final SymbolLookup symbolLookup = name -> systemLookup.lookup(name)
.or(() -> linkerLookup.lookup(name));
final MemorySegment addr = symbolLookup.lookup("GetCurrentDirectory")
.orElse(null);
...
The problem is, when debugging addr is null, so it looks like it can't find the method by this name. Do I somehow need to tell the lookup in what DLL it should look for this function (for a test with printf this was not necessary)?
Yes, you have to load the library that contains
GetCurrentDirectory, which isKernel32(according to the documentation):After loading a library with
System::loadorSystem::loadLibrary, it can be found using the loader lookup (i.e.SymbolLookup.loaderLookup()). See the documentation:Note that
System::loadLibraryalso requires the directory that contains the library to be listed in thejava.library.pathsystem property (you will get an exception if it's not). ForKernel32this should beC:\Windows\System32The reason it works for
printfis because you are using thedefaultLookupof thenativeLinkerwhich can find all the symbols in the standard C library.GetCurrentDirectoryis not a part of that library though.Furthermore, it looks like
GetCurrentDirectoryis defined as__inline, which means you can not link against it dynamically, as the symbol/function is simply not present inKernel32.dll, AFAICT:Instead, you have to look up and call
GetCurrentDirectoryAforchars orGetCurrentDirectoryWforwchar_ts directly: