Интерфейс CLinker
public sealed interface CLinker
Связывание внешней функции — это процесс, требующий двух компонентов: тип метода и дескриптор функции. Тип метода состоит из набора типов носителей, которые вместе задают сигнатуру Java, которой клиенты должны следовать при вызове основной внешней функции. Дескриптор функции содержит набор макетов памяти, которые вместе задают сигнатуру внешней функции и информацию о классификации (через пользовательские атрибуты макета, см. CLinker.TypeKind), чтобы связывание могло произойти.
Клиенты этого API могут создавать дескрипторы функций, используя предопределенные константы макетов памяти (на основе подмножества встроенных типов языка C), которые содержатся в этом интерфейсе; альтернативно, они также могут дополнять существующие макеты значений требуемым атрибутом классификации CLinker.TypeKind (это можно сделать с помощью метода MemoryLayout.withAttribute(String, Constable)). Отсутствие этого может привести к ошибкам связывания, так как связывание требует дополнительной информации о классификации для определения, например, того, как аргументы должны загружаться в регистры во время вызова внешней функции.
Реализации этого интерфейса поддерживают следующие примитивные типы носителей: byte, short, char, int, long, float, и double, а также MemoryAddress для передачи указателей и MemorySegment для передачи структур и объединений. Наконец, тип носителя CLinker.VaList может использоваться для сопоставления с родным типом va_list.
Для успешного процесса связывания должны быть соблюдены некоторые требования; если M и F — тип метода (полученный после удаления префиксных аргументов) и дескриптор функции соответственно, используемые во время процесса связывания, то должны выполняться следующие условия:
- Арность
Mдолжна быть такой же, как уF; - Если возвращаемый тип
Mравенvoid, тоFне должно иметь возвращаемого макета (см.FunctionDescriptor.ofVoid(MemoryLayout...)); - для каждой пары типа носителя
Cи макетаLвMиFсоответственно, гдеCиLотносятся к одному аргументу или возвращаемому значению, должны выполняться следующие условия:- Если
C— примитивный тип, тоLдолжен бытьValueLayout, а размер макета должен соответствовать размеру типа носителя (см.Integer.SIZEи аналогичные поля в других классах обёртки примитивных типов); - Если
C—MemoryAddress.class, тоLдолжен бытьValueLayout, а его размер должен соответствовать размеру адреса платформы (см.MemoryLayouts.ADDRESS). Для этой цели можно использовать константу макетаC_POINTER; - Если
C—MemorySegment.class, тоLдолжен бытьGroupLayout - Если
C—VaList.class, тоLдолжен бытьC_VA_LIST
- Если
Функции с переменным числом аргументов, объявленные в C с трейлинг-эллипсами (...) в конце списка формальных параметров или со пустым списком формальных параметров, не поддерживаются напрямую. Невозможно создать обработчик методов, принимающий переменное количество аргументов, а также невозможно создать заглушку upcall, оборачивающую обработчик методов, принимающий переменное количество аргументов. Однако только для downcalls можно связать нативную функцию с переменным числом аргументов, используя специализированный тип метода и дескриптор функции: для каждого аргумента, который должен передаваться как аргумент с переменным числом аргументов, должен присутствовать явный дополнительный тип носителя и макет памяти в типе метода и объектах дескриптора функции, переданных линкеру. Кроме того, поскольку макеты памяти, соответствующие аргументам с переменным числом аргументов в дескрипторе функции, должны содержать дополнительную информацию о классификации, требуется использовать asVarArg(MemoryLayout) для создания макетов памяти для каждого параметра, соответствующего аргументу с переменным числом аргументов в специализированном дескрипторе функции.
На платформах, которые не поддерживаются, этот класс не сможет инициализироваться с ExceptionInInitializerError.
Если не указано иное, передача аргумента null, или аргумента массива, содержащего один или несколько элементов null, в метод в этом классе вызывает исключение NullPointerException.
- Требования к реализации:
- Реализации этого интерфейса неизменяемы, потокобезопасны и неизменяемы.
Краткое описание вложенных классов
| Модификатор и тип | Интерфейс | Описание |
|---|---|---|
static enum |
CLinker.TypeKind |
Тип C. |
static interface |
CLinker.VaList |
Интерфейс, моделирующий тип C va_list. |
Краткое описание полей
| Модификатор и тип | Поле | Описание |
|---|---|---|
static final ValueLayout |
C_CHAR |
Макет типа C char. |
static final ValueLayout |
C_DOUBLE |
Макет типа C double. |
static final ValueLayout |
C_FLOAT |
Макет типа C float. |
static final ValueLayout |
C_INT |
Макет типа C int. |
static final ValueLayout |
C_LONG |
Макет типа C long. |
static final ValueLayout |
C_LONG_LONG |
Макет типа C long long. |
static final ValueLayout |
C_POINTER |
Нативный тип T*. |
static final ValueLayout |
C_SHORT |
Макет типа C short. |
static final MemoryLayout |
C_VA_LIST |
Макет типа C va_list. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
static MemoryAddress |
allocateMemory |
Выделяет память заданного размера с помощью malloc. |
static <T extends MemoryLayout> |
asVarArg |
Возвращает макет памяти, подходящий для использования в качестве макета для аргументов с переменным числом аргументов в специализированном описателе функций. |
MethodHandle |
downcallHandle |
Получает дескриптор внешнего метода с заданным типом и содержащим указанный описатель функции, который может использоваться для вызова целевой внешней функции по адресу. |
MethodHandle |
downcallHandle |
Получает дескриптор внешнего метода с заданным типом и содержащим указанный описатель функции, который может использоваться для вызова целевой внешней функции по указанному адресу. |
MethodHandle |
downcallHandle |
Получает дескриптор внешнего метода с заданным типом и содержащим указанный описатель функции, который может использоваться для вызова целевой внешней функции по указанному адресу. |
static void |
freeMemory |
Освобождает память, указанную заданным адресом памяти. |
static CLinker |
getInstance() |
Возвращает компоновщик C для текущей платформы. |
static SymbolLookup |
systemLookup() |
Получает системный поиск, подходящий для поиска символов в стандартных библиотеках C. |
static MemorySegment |
toCString |
Преобразует строку Java в строку C, закодированную в UTF-8 и завершающуюся нулём, сохраняя результат в сегменте памяти, связанном с предоставленным ресурсным копом. |
static MemorySegment |
toCString |
Преобразует строку Java в строку C, закодированную в UTF-8 и завершающуюся нулём, сохраняя результат в сегменте памяти, выделенном с помощью предоставленного аллокатора. |
static String |
toJavaString |
Преобразует строку C, закодированную в UTF-8 и завершающуюся нулём, хранящуюся по заданному адресу, в строку Java. |
static String |
toJavaString |
Преобразует строку C, закодированную в UTF-8 и завершающуюся нулём, хранящуюся по заданному адресу, в строку Java. |
MemoryAddress |
upcallStub |
Выделяет нативный заглушку с заданным копом, который может передаваться другим внешним функциям (в качестве указателя на функцию); вызов такого указателя на функцию из кода нативно приведет к выполнению предоставленного дескриптора метода. |
Подробное описание полей
C_CHAR
static final ValueLayout C_CHAR
charC_SHORT
static final ValueLayout C_SHORT
shortC_INT
static final ValueLayout C_INT
intC_LONG
static final ValueLayout C_LONG
longC_LONG_LONG
static final ValueLayout C_LONG_LONG
long long. C_FLOAT
static final ValueLayout C_FLOAT
floatC_DOUBLE
static final ValueLayout C_DOUBLE
doubleC_POINTER
static final ValueLayout C_POINTER
C_VA_LIST
static final MemoryLayout C_VA_LIST
va_listПодробное описание методов
getInstance
static CLinker getInstance()
Этот метод ограничен. Ограниченные методы небезопасны и, если их использовать неправильно, их использование может привести к аварийному завершению JVM или, что еще хуже, к скрытому повреждению памяти. Поэтому клиенты должны воздерживаться от зависимости от ограниченных методов и, по возможности, использовать безопасные и поддерживаемые функциональные возможности.
- Возвращает:
- компоновщик для этой системы.
- Имеет исключения:
-
IllegalCallerException- если доступ к этому методу осуществляется из модуляM, и параметр командной строки--enable-native-accessотсутствует, или не упоминает имя модуляM, илиALL-UNNAMEDв случае, еслиMявляется безымянным модулем.
systemLookup
static SymbolLookup systemLookup()
Этот метод ограничен. Ограниченные методы небезопасны и, если их использовать неправильно, их использование может привести к аварийному завершению JVM или, что еще хуже, к скрытому повреждению памяти. Поэтому клиенты должны воздерживаться от зависимости от ограниченных методов и, по возможности, использовать безопасные и поддерживаемые функциональные возможности.
- Возвращает:
- поиск библиотеки, специфичный для системы, подходящий для поиска символов в стандартных библиотеках C.
- Имеет исключения:
-
IllegalCallerException- если доступ к этому методу осуществляется из модуляM, и параметр командной строки--enable-native-accessотсутствует, или не упоминает имя модуляM, илиALL-UNNAMEDв случае, еслиMявляется безымянным модулем.
downcallHandle
MethodHandle downcallHandle(Addressable symbol, MethodType type, FunctionDescriptor function)
Если тип возвращаемого значения предоставленного типа метода — MemorySegment, то полученный обработчик метода содержит дополнительный параметр префикса типа SegmentAllocator, который будет использоваться runtime компоновщиком для выделения структур, возвращаемых по значению.
- Параметры:
-
symbol- символ обратного вызова. -
type- тип метода. -
function- описание функции. - Возвращает:
- обработчик метода обратного вызова.
- Имеет исключения:
-
IllegalArgumentException- в случае несоответствия типа метода и описания функции, или если символ являетсяMemoryAddress.NULL - См. также:
downcallHandle
MethodHandle downcallHandle(Addressable symbol, SegmentAllocator allocator, MethodType type, FunctionDescriptor function)
Если тип возвращаемого значения предоставленного типа метода — MemorySegment, то предоставленный выделенный объект памяти будет использоваться runtime компоновщиком для выделения структур, возвращаемых по значению.
- Параметры:
-
symbol- символ обратного вызова. -
allocator- выделенный объект памяти. -
type- тип метода. -
function- описание функции. - Возвращает:
- обработчик метода обратного вызова.
- Имеет исключения:
-
IllegalArgumentException- в случае несоответствия типа метода и описания функции, или если символ являетсяMemoryAddress.NULL - См. также:
downcallHandle
MethodHandle downcallHandle(MethodType type, FunctionDescriptor function)
Addressable. Если тип возвращаемого значения предоставленного типа метода — MemorySegment, то результирующий обработчик метода содержит дополнительный параметр префикса (вставленный сразу после параметра адреса), типа SegmentAllocator, который будет использоваться runtime компоновщиком для выделения структур, возвращаемых по значению.
Возвращаемый обработчик метода выбросит IllegalArgumentException, если целевой адрес, переданный ему, равен MemoryAddress.NULL, или NullPointerException, если целевой адрес — null.
- Параметры:
-
type- тип метода. -
function- описание функции. - Возвращает:
- обработчик метода обратного вызова.
- Имеет исключения:
-
IllegalArgumentException- в случае несоответствия типа метода и описания функции. - См. также:
upcallStub
MemoryAddress upcallStub(MethodHandle target, FunctionDescriptor function, ResourceScope scope)
Возвращаемый адрес памяти связан с предоставленным объемом. При закрытии такого объема соответствующая нативная заглушка будет освобождена.
Целевой обработчик метода не должен генерировать исключения. Если целевой обработчик метода выбросит исключение, VM завершится с ненулевым кодом выхода. Чтобы предотвратить аварийное завершение VM из-за необработанного исключения, клиенты могли бы обернуть весь код в целевом обработчике метода в блок try/catch, который ловит любой Throwable, например, используя MethodHandles.catchException(MethodHandle, Class, MethodHandle) комбинатор обработчика метода, и обработать исключения как нужно в соответствующем блоке catch.
- Параметры:
-
target- целевой обработчик метода. -
function- описание функции. -
scope- объем заглушки обратного вызова. - Возвращает:
- сегмент нативной заглушки.
- Имеет исключения:
-
IllegalArgumentException- если тип метода цели и описание функции не совпадают. -
IllegalStateException- еслиscopeуже закрыт, или если доступ происходит из потока, отличного от потока, владеющегоscope.
asVarArg
static <T extends MemoryLayout> T asVarArg(T layout)
- Параметры типа:
-
T- тип макета памяти - Параметры:
-
layout- макет для адаптации - Возвращает:
- возможно, новый макет с нужными атрибутами
toCString
static MemorySegment toCString(String str, SegmentAllocator allocator)
Этот метод всегда заменяет некорректные входные данные и неотображаемые символы на массив байтов-заменителей по умолчанию для этого набора символов. Класс CharsetEncoder следует использовать, если требуется больший контроль над процессом кодирования.
- Parameters:
-
str- строка Java, которая должна быть преобразована в строку C. -
allocator- аллокатор, который должен быть использован для выделения сегмента. - Returns:
- новый сегмент памяти, содержащий преобразованную строку C.
toCString
static MemorySegment toCString(String str, ResourceScope scope)
Этот метод всегда заменяет некорректные входные данные и неотображаемые символы на массив байтов-заменителей по умолчанию для этого набора символов. Класс CharsetEncoder следует использовать, если требуется больший контроль над процессом кодирования.
- Parameters:
-
str- строка Java, которая должна быть преобразована в строку C. -
scope- ресурсное пространство, которое должно быть связано с возвращённым сегментом. - Returns:
- новый сегмент памяти, содержащий преобразованную строку C.
- Throws:
-
IllegalStateException- еслиscopeуже закрыто, или если доступ происходит из потока, отличного от потока, владеющегоscope.
toJavaString
static String toJavaString(MemoryAddress addr)
Этот метод всегда заменяет некорректные входные данные и неотображаемые символы на строку-заменитель по умолчанию для этого набора символов. Класс CharsetDecoder следует использовать, если требуется больший контроль над процессом декодирования.
Этот метод ограничен. Ограниченные методы небезопасны, и при неправильном использовании их использование может привести к аварийному завершению JVM или, что ещё хуже, к неявной порче памяти. Таким образом, клиенты должны воздерживаться от зависимости от ограниченных методов и использовать безопасные и поддерживаемые функции, где это возможно.
- Parameters:
-
addr- адрес, по которому хранится строка. - Returns:
- строка Java с содержимым завершающейся нулём строки C по данному адресу.
- Throws:
-
IllegalArgumentException- если размер родной строки больше максимальной поддерживаемой платформой строки, или еслиaddr == MemoryAddress.NULL. -
IllegalCallerException- если доступ к этому методу происходит из модуляMи опция командной строки--enable-native-accessлибо отсутствует, либо не упоминает имя модуляM, илиALL-UNNAMEDв случае, еслиMявляется безымянным модулем.
toJavaString
static String toJavaString(MemorySegment addr)
Этот метод всегда заменяет некорректные входные данные и неотображаемые символы на строку-заменитель по умолчанию для этого набора символов. Класс CharsetDecoder следует использовать, если требуется больший контроль над процессом декодирования.
- Parameters:
-
addr- адрес, по которому хранится строка. - Returns:
- строка Java с содержимым завершающейся нулём строки C по данному адресу.
- Throws:
-
IllegalArgumentException- если размер родной строки больше максимальной поддерживаемой платформой строки. -
IllegalStateException- если размер родной строки больше размера сегмента, связанного сaddr, или еслиaddrсвязано с сегментом, который не активен.
allocateMemory
static MemoryAddress allocateMemory(long size)
Этот метод ограничен. Ограниченные методы небезопасны, и при неправильном использовании их использование может привести к аварийному завершению JVM или, что ещё хуже, к неявной порче памяти. Таким образом, клиенты должны воздерживаться от зависимости от ограниченных методов и использовать безопасные и поддерживаемые функции, где это возможно.
- Parameters:
-
size- размер памяти для выделения - Returns:
- адрес памяти addr выделенной памяти
- Throws:
-
OutOfMemoryError- если malloc не смог выделить требуемое количество родной памяти. -
IllegalCallerException- если доступ к этому методу происходит из модуляMи опция командной строки--enable-native-accessлибо отсутствует, либо не упоминает имя модуляM, илиALL-UNNAMEDв случае, еслиMявляется безымянным модулем.
freeMemory
static void freeMemory(MemoryAddress addr)
Этот метод ограничен. Ограниченные методы небезопасны, и при неправильном использовании их использование может привести к аварийному завершению JVM или, что ещё хуже, к неявной порче памяти. Таким образом, клиенты должны воздерживаться от зависимости от ограниченных методов и использовать безопасные и поддерживаемые функции, где это возможно.
- Parameters:
-
addr- адрес памяти родной памяти, которая должна быть освобождена - Throws:
-
IllegalCallerException- если доступ к этому методу происходит из модуляMи опция командной строки -
IllegalArgumentException- еслиaddr == MemoryAddress.NULL.--enable-native-accessлибо отсутствует, либо не упоминает имя модуляM, илиALL-UNNAMEDв случае, еслиMявляется безымянным модулем.
© 1993, 2021, 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/17/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/CLinker.html