Spec-Zone.ru › OpenJDK 25

Интерфейс 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 будут загружены другие библиотеки и связаны с загрузчиком классов, поиск через загрузчик автоматически предоставит доступ к их символам.

Обратите внимание, что поиск через загрузчик предоставляет доступ только к символам библиотек, ранее загруженных через 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<MemorySegment> find(String name)
Возвращает адрес символа с указанным именем.
default MemorySegment findOrThrow(String name)
Возвращает адрес символа с указанным именем или выбрасывает исключение.
static SymbolLookup libraryLookup(String name, Arena arena)
Ограниченный.
Загружает библиотеку с указанным именем (если она еще не загружена) и создает поиск символов для символов в этой библиотеке.
static SymbolLookup libraryLookup(Path path, Arena arena)
Ограниченный.
Загружает библиотеку по указанному пути (если она еще не загружена) и создает поиск символов для символов в этой библиотеке.
static SymbolLookup loaderLookup()
Возвращает поиск символов в библиотеках, связанных с загрузчиком классов вызывающего кода.
default SymbolLookup or(SymbolLookup other)
Возвращает составной поиск символов, который возвращает результат поиска символа с помощью этого поиска, если символ найден, а в противном случае возвращает результат поиска символа с помощью другого поиска.

Подробное описание методов

find

Optional<MemorySegment> find(String name)
Возвращает адрес символа с указанным именем.
Параметры:
name — имя символа
Возвращает:
сегмент памяти нулевой длины, адрес которого указывает на адрес символа, если он найден
См. также:
  • findOrThrow(String)

findOrThrow

default MemorySegment findOrThrow(String name)
Возвращает адрес символа с указанным именем или выбрасывает исключение.

Это эквивалентно следующему коду, но работает эффективнее:

   String name = ...
   MemorySegment address = lookup.find(name)
       .orElseThrow(() -> new NoSuchElementException("Symbol not found: " + name));
Параметры:
name — имя символа
Возвращает:
сегмент памяти нулевой длины, адрес которого указывает на адрес символа
Выбрасывает:
NoSuchElementException — если для указанного имени не найден адрес символа
Начиная с версии:
23
См. также:
  • find(String)

or

default SymbolLookup or(SymbolLookup other)
Возвращает составной поиск символов, который возвращает результат поиска символа с помощью этого поиска, если символ найден, а в противном случае возвращает результат поиска символа с помощью другого поиска.
Примечание API:
Этот метод можно использовать для объединения нескольких поисков символов, например, чтобы символы можно было искать по очереди в нескольких библиотеках:
 var lookup = SymbolLookup.libraryLookup("foo", arena)
         .or(SymbolLookup.libraryLookup("bar", arena))
         .or(SymbolLookup.loaderLookup());
Приведенный выше код создает поиск символов, который сначала ищет символы в библиотеке "foo". Если символ не найден в "foo", выполняется поиск в "bar". Наконец, если символ не найден ни в "foo", ни в "bar", используется поиск через загрузчик.
Параметры:
other — поиск символов, который следует использовать для поиска символов, не найденных с помощью этого поиска
Возвращает:
составной поиск символов, который возвращает результат поиска символа с помощью этого поиска, если символ найден, а в противном случае возвращает результат поиска символа с помощью другого поиска

loaderLookup

static SymbolLookup loaderLookup()
Возвращает поиск символов в библиотеках, связанных с загрузчиком классов вызывающего кода.

Библиотека связывается с загрузчиком классов CL при загрузке посредством вызова System.load(String)ОГРАНИЧЕННЫЙ или System.loadLibrary(String)ОГРАНИЧЕННЫЙ из кода класса, определенного CL. Если этот код выполняет последующие вызовы System.load(String)ОГРАНИЧЕННЫЙ или System.loadLibrary(String)ОГРАНИЧЕННЫЙ, загружаются новые библиотеки и связываются с CL. Поиск символов, возвращаемый этим методом, всегда актуален: он учитывает все библиотеки, связанные с соответствующим загрузчиком классов, даже если они были загружены после возврата этого метода.

Библиотеки, связанные с загрузчиком классов, выгружаются, когда загрузчик классов становится недостижимым. Поиск символов, возвращаемый этим методом, связан с автоматической областью видимости, которая удерживает загрузчик классов вызывающего кода достижимым. Поэтому библиотеки, связанные с загрузчиком классов вызывающего кода, остаются загруженными (а их символы — доступными), пока остается достижимым поиск через этот загрузчик или любой полученный с его помощью сегмент.

Если этот метод вызывается в контексте, где в стеке нет кадра вызывающего кода (например, при прямом вызове из присоединенного потока JNI), по умолчанию используется системный загрузчик классов.

Возвращает:
поиск символов в библиотеках, связанных с загрузчиком классов вызывающего кода
См. также:
  • System.load(String)ОГРАНИЧЕННЫЙ
  • System.loadLibrary(String)ОГРАНИЧЕННЫЙ

libraryLookup

static SymbolLookup libraryLookup(String name, Arena arena)
libraryLookup является ограниченным методом платформы Java.
Программы могут использовать libraryLookup только при включенном доступе к ограниченным методам.
Ограниченные методы небезопасны: при неправильном использовании они могут привести к аварийному завершению JVM или повреждению памяти.
Загружает библиотеку с указанным именем (если она еще не загружена) и создает поиск символов для символов в этой библиотеке. Время существования возвращаемого поиска по библиотеке контролируется предоставленной ареной. Например, если предоставленная арена является ограниченной ареной, связанная с возвращаемым поиском библиотека выгружается при закрытии предоставленной ограниченной арены.
Примечание по реализации:
Процесс разрешения имени библиотеки зависит от операционной системы. Например, в ОС, совместимой с 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 только при включенном доступе к ограниченным методам.
Ограниченные методы небезопасны: при неправильном использовании они могут привести к аварийному завершению JVM или повреждению памяти.
Загружает библиотеку по указанному пути (если она еще не загружена) и создает поиск символов для символов в этой библиотеке. Время существования возвращаемого поиска по библиотеке контролируется предоставленной ареной. Например, если предоставленная арена является ограниченной ареной, связанная с возвращаемым поиском библиотека выгружается при закрытии предоставленной ограниченной арены.
Примечание по реализации:
В Linux функции, предоставляемые этим фабричным методом и возвращаемым поиском символов, реализованы с использованием функций dlopen, dlsym и dlclose.
Параметры:
path — путь к библиотеке, в которой следует искать символы
arena — арена, связанная с символами, полученными с помощью возвращаемого поиска
Возвращает:
новый поиск символов, предназначенный для поиска символов в библиотеке по указанному пути
Выбрасывает:
IllegalStateException — если arena.scope().isAlive() == false
WrongThreadException — если arena является ограниченной ареной, а этот метод вызван из потока T, отличного от потока-владельца арены
IllegalArgumentException — если path не указывает на допустимую библиотеку в файловой системе по умолчанию
IllegalCallerException — если вызывающий код находится в модуле, для которого не включен доступ к нативному коду

Сообщить об ошибке или предложить улучшение
Дополнительные справочные материалы по API и документацию для разработчиков см. в разделе документация Java SE, содержащем более подробные описания для разработчиков, включая концептуальные обзоры, определения терминов, обходные решения и рабочие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или ее аффилированных лиц в США и других странах.
Авторские права © 1993, 2025, Oracle и/или ее аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API