Интерфейс SymbolLookup
- Функциональный интерфейс:
- Это функциональный интерфейс, поэтому его можно использовать в качестве цели присваивания для лямбда-выражения или ссылки на метод.
@FunctionalInterface public interface SymbolLookup
Поиск символов создается для определенной библиотеки (или библиотек). Затем метод find(String) принимает имя символа и возвращает адрес символа в этой библиотеке.
Адрес символа представляется сегментом памяти нулевой длины memory segment. Сегмент можно использовать по-разному:
- Его можно передать объекту
Linker, чтобы создать дескриптор метода для вызова внешней функции, который затем можно использовать для вызова внешней функции по адресу сегмента. - Его можно передать существующему дескриптору метода для вызова внешней функцииОГРАНИЧЕННЫЙ в качестве аргумента базовой внешней функции.
- Его можно сохранить внутри другого сегмента памяти.
- Его можно использовать для доступа к области памяти, в которой хранится глобальная переменная (для этого сначала требуется изменить размерОГРАНИЧЕННЫЙ сегмента).
Получение поиска символов
Фабричные методыlibraryLookup(String, Arena)ОГРАНИЧЕННЫЙ и libraryLookup(Path, Arena)ОГРАНИЧЕННЫЙ создают поиск символов для библиотеки, известной операционной системе. Библиотека указывается либо по имени, либо по пути. Если библиотека еще не загружена, она загружается. Поиск символов, называемый поиском по библиотеке, и время его существования контролируются ареной arena. Например, если предоставленная арена является ограниченной ареной, связанная с поиском символов библиотека выгружается при закрытии ограниченной арены: 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
Если библиотека ранее была загружена через JNI, то есть с помощью System.load(String)ОГРАНИЧЕННЫЙ или System.loadLibrary(String)ОГРАНИЧЕННЫЙ, то она также была связана с определенным загрузчиком классов. Фабричный метод loaderLookup() создает поиск символов для всех библиотек, связанных с загрузчиком классов вызывающего кода:
System.loadLibrary("GL"); // libGL.so loaded here
...
SymbolLookup libGL = SymbolLookup.loaderLookup();
MemorySegment glGetString = libGL.findOrThrow("glGetString");
Обратите внимание, что поиск через загрузчик предоставляет доступ только к символам библиотек, ранее загруженных через JNI, то есть с помощью System.load(String)ОГРАНИЧЕННЫЙ или System.loadLibrary(String)ОГРАНИЧЕННЫЙ. Поиск через загрузчик не предоставляет доступ к символам библиотек, загруженных при создании поиска по библиотеке:
libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true
loaderLookup().find("glGetString").isPresent(); // false
L предоставляет доступ к символам в L, даже если L ранее была загружена через JNI (связь с загрузчиком классов не имеет значения для поиска по библиотеке): System.loadLibrary("GL"); // libGL.so loaded here
libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true
Наконец, каждый Linker предоставляет поиск символов для библиотек, обычно используемых в сочетании операционной системы и процессора, поддерживаемом этим Linker. Этот поиск символов, называемый поиском по умолчанию, позволяет клиентам быстро находить адреса известных символов. Например, Linker для Linux/x64 может предоставлять через поиск по умолчанию доступ к символам в libc:
Linker nativeLinker = Linker.nativeLinker();
SymbolLookup stdlib = nativeLinker.defaultLookup();
MemorySegment malloc = stdlib.findOrThrow("malloc");
- Начиная с версии:
- 22
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
Optional |
find |
Возвращает адрес символа с указанным именем. |
default MemorySegment |
findOrThrow |
Возвращает адрес символа с указанным именем или выбрасывает исключение. |
static SymbolLookup |
libraryLookup |
Ограниченный. Загружает библиотеку с указанным именем (если она еще не загружена) и создает поиск символов для символов в этой библиотеке. |
static SymbolLookup |
libraryLookup |
Ограниченный. Загружает библиотеку по указанному пути (если она еще не загружена) и создает поиск символов для символов в этой библиотеке. |
static SymbolLookup |
loaderLookup() |
Возвращает поиск символов в библиотеках, связанных с загрузчиком классов вызывающего кода. |
default SymbolLookup |
or |
Возвращает составной поиск символов, который возвращает результат поиска символа с помощью этого поиска, если символ найден, а в противном случае возвращает результат поиска символа с помощью другого поиска. |
Подробное описание методов
find
Optional<MemorySegment> find(String name)
- Параметры:
-
name— имя символа - Возвращает:
- сегмент памяти нулевой длины, адрес которого указывает на адрес символа, если он найден
- См. также:
findOrThrow
default MemorySegment findOrThrow(String name)
Это эквивалентно следующему коду, но работает эффективнее:
String name = ...
MemorySegment address = lookup.find(name)
.orElseThrow(() -> new NoSuchElementException("Symbol not found: " + name));
- Параметры:
-
name— имя символа - Возвращает:
- сегмент памяти нулевой длины, адрес которого указывает на адрес символа
- Выбрасывает:
-
NoSuchElementException— если для указанного имени не найден адрес символа - Начиная с версии:
- 23
- См. также:
or
default SymbolLookup or(SymbolLookup other)
- Примечание API:
- Этот метод можно использовать для объединения нескольких поисков символов, например, чтобы символы можно было искать по очереди в нескольких библиотеках: Приведенный выше код создает поиск символов, который сначала ищет символы в библиотеке "foo". Если символ не найден в "foo", выполняется поиск в "bar". Наконец, если символ не найден ни в "foo", ни в "bar", используется поиск через загрузчик.
var lookup = SymbolLookup.libraryLookup("foo", arena) .or(SymbolLookup.libraryLookup("bar", arena)) .or(SymbolLookup.loaderLookup()); - Параметры:
-
other— поиск символов, который следует использовать для поиска символов, не найденных с помощью этого поиска - Возвращает:
- составной поиск символов, который возвращает результат поиска символа с помощью этого поиска, если символ найден, а в противном случае возвращает результат поиска символа с помощью другого поиска
loaderLookup
static SymbolLookup loaderLookup()
Библиотека связывается с загрузчиком классов CL при загрузке посредством вызова System.load(String)ОГРАНИЧЕННЫЙ или System.loadLibrary(String)ОГРАНИЧЕННЫЙ из кода класса, определенного CL. Если этот код выполняет последующие вызовы System.load(String)ОГРАНИЧЕННЫЙ или System.loadLibrary(String)ОГРАНИЧЕННЫЙ, загружаются новые библиотеки и связываются с CL. Поиск символов, возвращаемый этим методом, всегда актуален: он учитывает все библиотеки, связанные с соответствующим загрузчиком классов, даже если они были загружены после возврата этого метода.
Библиотеки, связанные с загрузчиком классов, выгружаются, когда загрузчик классов становится недостижимым. Поиск символов, возвращаемый этим методом, связан с автоматической областью видимости, которая удерживает загрузчик классов вызывающего кода достижимым. Поэтому библиотеки, связанные с загрузчиком классов вызывающего кода, остаются загруженными (а их символы — доступными), пока остается достижимым поиск через этот загрузчик или любой полученный с его помощью сегмент.
Если этот метод вызывается в контексте, где в стеке нет кадра вызывающего кода (например, при прямом вызове из присоединенного потока JNI), по умолчанию используется системный загрузчик классов.
- Возвращает:
- поиск символов в библиотеках, связанных с загрузчиком классов вызывающего кода
- См. также:
libraryLookup
static SymbolLookup libraryLookup(String name, Arena arena)
libraryLookup является ограниченным методом платформы Java. - Примечание по реализации:
- Процесс разрешения имени библиотеки зависит от операционной системы. Например, в ОС, совместимой с POSIX, имя библиотеки разрешается в соответствии со спецификацией функции
dlopenдля этой ОС. В Windows имя библиотеки разрешается в соответствии со спецификацией функцииLoadLibrary. - Параметры:
-
name— имя библиотеки, в которой следует искать символы -
arena— арена, связанная с символами, полученными с помощью возвращаемого поиска - Возвращает:
- новый поиск символов, предназначенный для поиска символов в библиотеке с указанным именем
- Выбрасывает:
-
IllegalStateException— еслиarena.scope().isAlive() == false -
WrongThreadException— еслиarenaявляется ограниченной ареной, а этот метод вызван из потокаT, отличного от потока-владельца арены -
IllegalArgumentException— еслиnameне указывает на допустимую библиотеку -
IllegalCallerException— если вызывающий код находится в модуле, для которого не включен доступ к нативному коду
libraryLookup
static SymbolLookup libraryLookup(Path path, Arena arena)
libraryLookup является ограниченным методом платформы Java. libraryLookup только при включенном доступе к ограниченным методам.- Примечание по реализации:
- В Linux функции, предоставляемые этим фабричным методом и возвращаемым поиском символов, реализованы с использованием функций
dlopen,dlsymиdlclose. - Параметры:
-
path— путь к библиотеке, в которой следует искать символы -
arena— арена, связанная с символами, полученными с помощью возвращаемого поиска - Возвращает:
- новый поиск символов, предназначенный для поиска символов в библиотеке по указанному пути
- Выбрасывает:
-
IllegalStateException— еслиarena.scope().isAlive() == false -
WrongThreadException— еслиarenaявляется ограниченной ареной, а этот метод вызван из потокаT, отличного от потока-владельца арены -
IllegalArgumentException— еслиpathне указывает на допустимую библиотеку в файловой системе по умолчанию -
IllegalCallerException— если вызывающий код находится в модуле, для которого не включен доступ к нативному коду
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/foreign/SymbolLookup.html
libraryLookupтолько при включенном доступе к ограниченным методам.