- 适用于 JDK 24 的 GraalVM(最新)
- 适用于 JDK 25 的 GraalVM(早期访问)
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- 存档
- 开发构建
原生镜像中的外部函数和内存 API
外部函数和内存 (FFM) API 是一种接口,它使 Java 代码能够与原生代码交互,反之亦然。它在 JDK 22 中通过 JEP 454 最终确定。目前,在 Native Image 中的支持是实验性的,并且必须通过 -H:+ForeignAPISupport
(以及 -H:+UnlockExperimentalVMOptions
)明确启用。允许执行“受限”原生操作(包括创建用于调用或被原生代码调用的句柄)的模块必须使用 --enable-native-access=
选项指定。本页面概述了 Native Image 中 FFM API 的支持情况。
外部内存 #
外部内存功能通常受支持。共享竞技场目前不受支持。
外部函数 #
FFM API 使 Java 代码能够 *向下* 调用原生函数,反之,也允许原生代码 *向上* 通过方法句柄调用 Java 代码。这两种调用分别称为“下调 (downcalls)”和“上调 (upcalls)”,统称为“外部调用 (foreign calls)”。
注意:目前,外部调用在 x64 架构上受支持。具体来说,下调在 x64 Linux、Windows 和 MacOS 上受支持,而上调仅在 x64 Linux 上受支持。
查找原生函数 #
FFM API 提供了 SymbolLookup
接口,用于按名称在原生库中查找函数。SymbolLookup.loaderLookup()
是目前唯一受支持的 SymbolLookup
类型。
注册外部调用 #
为了在运行时对原生代码进行调用,必须在镜像构建时生成支持代码。因此,必须向 native-image
工具提供描述符,这些描述符描述了可在运行时执行下调的函数。
这些描述符可以使用自定义 Feature
进行注册,例如
import static java.lang.foreign.ValueLayout.*;
class ForeignRegistrationFeature implements Feature {
public void duringSetup(DuringSetupAccess access) {
RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.ofVoid());
RuntimeForeignAccess.registerForUpcall(FunctionDescriptor.ofVoid());
RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.ofVoid(), Linker.Option.critical(false));
RuntimeForeignAccess.registerForUpcall(FunctionDescriptor.of(JAVA_INT, JAVA_INT));
RuntimeForeignAccess.registerForUpcall(FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT));
RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.of(ADDRESS, JAVA_INT, JAVA_INT), Linker.Option.firstVariadicArg(1));
RuntimeForeignAccess.registerForDowncall(FunctionDescriptor.ofVoid(JAVA_INT), Linker.Option.captureCallState("errno"));
}
}
要激活自定义功能,请将 --features=com.example.ForeignRegistrationFeature
选项(功能类的完全限定名)传递给 native-image
。建议 通过 *native-image.properties* 文件 来实现。