A symbol lookup is created with respect to a particular library (or libraries).
Subsequently, the SymbolLookup#find(String) method takes the name of a symbol
and returns the address of the symbol in that library.
The address of a symbol is modeled as a zero-length memory segment. The segment can be used in different ways:
Linker to create a downcall method handle, which
can then be used to call the foreign function at the segment's address.libraryLookup(String, Arena) and
libraryLookup(Path, Arena) create a symbol lookup for a library known to
the operating system. The library is specified by either its name or a path.
The library is loaded if not already loaded. The symbol lookup, which is known as a
library lookup, and its lifetime is controlled by an arena.
For instance, if the provided arena is a confined arena, the library associated with
the symbol lookup is unloaded when the confined arena is closed:
try (Arena arena = Arena.ofConfined()) { SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so", arena); // libGL.so loaded here MemorySegment glGetString = libGL.findOrThrow("glGetString"); ... } // libGL.so unloaded here
If a library was previously loaded through JNI, i.e., by System#load(String)
or System#loadLibrary(String), then the library was also associated with
a particular class loader. The factory method loaderLookup() creates
a symbol lookup for all the libraries associated with the caller's class loader:
System.loadLibrary("GL"); // libGL.so loaded here ... SymbolLookup libGL = SymbolLookup.loaderLookup(); MemorySegment glGetString = libGL.findOrThrow("glGetString");
Note that a loader lookup only exposes symbols in libraries that were previously
loaded through JNI, i.e., by System#load(String) or System#loadLibrary(String).
A loader lookup does not expose symbols in libraries that were loaded in the course
of creating a library lookup:
libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true loaderLookup().find("glGetString").isPresent(); // false
L exposes symbols in L
even if L was previously loaded through JNI (the association with
a class loader is immaterial to the library lookup):
System.loadLibrary("GL"); // libGL.so loaded here libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true
Finally, each Linker provides a symbol lookup for libraries that are commonly
used on the OS and processor combination supported by that Linker. This
symbol lookup, which is known as a default lookup, helps clients to quickly
find addresses of well-known symbols. For example, a Linker for Linux/x64
might choose to expose symbols in libc through the default lookup:
Linker nativeLinker = Linker.nativeLinker(); SymbolLookup stdlib = nativeLinker.defaultLookup(); MemorySegment malloc = stdlib.findOrThrow("malloc");
| Modifier and Type | Method and Description |
|---|---|
| public Optional | |
| public default MemorySegment | Returns: a zero-length memory segment whose address indicates the address of the symbolthe symbol name name)Returns the address of the symbol with the given name or throws an exception. |
| public static SymbolLookup | Returns: a new symbol lookup suitable to find symbols in a library with the given namethe name of the library in which symbols should be looked up name, Arena the arena associated with symbols obtained from the returned lookup arena)Loads a library with the given name (if not already loaded) and creates a symbol lookup for symbols in that library. |
| public static SymbolLookup | Returns: a new symbol lookup suitable to find symbols in a library with the given paththe path of the library in which symbols should be looked up path, Arena the arena associated with symbols obtained from the returned lookup arena)Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library. |
| private static <Z> SymbolLookup | libraryLookup(Z libDesc, BiFunction<RawNativeLibraries, Z, NativeLibrary> loadLibraryFunc, Arena libArena)
|
| public static SymbolLookup | Returns: a symbol lookup for symbols in the libraries associated with the caller's class loaderReturns a symbol lookup for symbols in the libraries associated with the caller's class loader. |
| public default SymbolLookup | Returns: a composed symbol lookup that returns the result of finding the symbol with this lookup if found, otherwise returns the result of finding the symbol with the other lookupthe symbol lookup that should be used to look for symbols not found
in this lookup other)Returns a composed symbol lookup that returns the result of finding the symbol with this lookup if found, otherwise returns the result of finding the symbol with the other lookup. |
| find | back to summary |
|---|---|
| public Optional Returns the address of the symbol with the given name.
| |
| findOrThrow | back to summary |
|---|---|
| public default MemorySegment findOrThrow(String name) Returns the address of the symbol with the given name or throws an exception. This is equivalent to the following code, but is more efficient: to: String name = ... MemorySegment address = lookup.find(name) .orElseThrow(() -> new NoSuchElementException("Symbol not found: " + name));
| |
| libraryLookup | back to summary |
|---|---|
| public static SymbolLookup libraryLookup(String name, Arena arena) Loads a library with the given name (if not already loaded) and creates a symbol lookup for symbols in that library. The lifetime of the returned library lookup is controlled by the provided arena. For instance, if the provided arena is a confined arena, the library associated with the returned lookup will be unloaded when the provided confined arena is closed. Implementation Note The process of resolving a library name is OS-specific. For instance,
in a POSIX-compliant OS, the library name is resolved according to the
specification of the
| |
| libraryLookup | back to summary |
|---|---|
| public static SymbolLookup libraryLookup(Path path, Arena arena) Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library. The lifetime of the returned library lookup is controlled by the provided arena. For instance, if the provided arena is a confined arena, the library associated with the returned lookup will be unloaded when the provided confined arena is closed. Implementation Note On Linux, the functionalities provided by this factory method and the
returned symbol lookup are implemented using the
| |
| libraryLookup | back to summary |
|---|---|
private static <Z> SymbolLookup libraryLookup(Z libDesc, BiFunction<RawNativeLibraries, Z, NativeLibrary> loadLibraryFunc, Arena libArena)
| |
| loaderLookup | back to summary |
|---|---|
| public static SymbolLookup loaderLookup() Returns a symbol lookup for symbols in the libraries associated with the caller's class loader.
A library is associated with a class loader Libraries associated with a class loader are unloaded when the class loader becomes unreachable. The symbol lookup returned by this method is associated with an automatic scope which keeps the caller's class loader reachable. Therefore, libraries associated with the caller's class loader are kept loaded (and their symbols available) as long as a loader lookup for that class loader, or any of the segments obtained by it, is reachable. In cases where this method is called from a context where there is no caller frame on the stack (e.g. when called directly from a JNI attached thread), the caller's class loader defaults to the system class loader.
| |
| or | back to summary |
|---|---|
| public default SymbolLookup or(SymbolLookup other) Returns a composed symbol lookup that returns the result of finding the symbol with this lookup if found, otherwise returns the result of finding the symbol with the other lookup. API Note This method could be used to chain multiple symbol lookups together, e.g. so that symbols could be retrieved, in order, from multiple libraries: var lookup = SymbolLookup.libraryLookup("foo", arena) .or(SymbolLookup.libraryLookup("bar", arena)) .or(SymbolLookup.loaderLookup());
| |