Spec-Zone.ru › OpenJDK 24

Интерфейс SymbolLookup

Функциональный интерфейс:
Это функциональный интерфейс и, следовательно, может использоваться в качестве целевого назначения для лямбда-выражения или ссылки на метод.
@FunctionalInterface public interface SymbolLookup
Поиск символа извлекает адрес символа в одной или нескольких библиотеках. Символ — это именованная сущность, например, функция или глобальная переменная.

Поиск символа выполняется относительно конкретной библиотеки (или библиотек). Впоследствии метод find(String) принимает имя символа и возвращает адрес символа в этой библиотеке.

Адрес символа моделируется как сегмент памяти нулевой длины memory segment. Сегмент можно использовать различными способами:

  • Он может быть передан Linker для создания обработчика вызова вниз, который затем может использоваться для вызова внешней функции по адресу сегмента.
  • Он может быть передан существующему обработчику вызова вниз downcall method handleОГРАНИЧЕН в качестве аргумента для подлежащей внешней функции.
  • Он может быть сохранён внутри другого сегмента памяти.
  • Он может использоваться для доступа к области памяти, поддерживающей глобальную переменную (для этого требуется изменить размерОГРАНИЧЕН сегмента сначала).

Получение поиска символа

Методы-фабрики libraryLookup(String, Arena)ОГРАНИЧЕН и libraryLookup(Path, 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 - если вызывающий элемент находится в модуле, у которого не включен доступ к нативным функциям

© 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://download.java.net/java/early_access/jdk24/docs/api/java.base/java/lang/foreign/SymbolLookup.html

Spec-Zone.ru

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