- 適用於 JDK 23 的 GraalVM (最新版)
- 適用於 JDK 24 的 GraalVM (搶先體驗版)
- 適用於 JDK 21 的 GraalVM
- 適用於 JDK 17 的 GraalVM
- 封存
- 開發建置
Native Image 中的外部函式與記憶體 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 程式碼。這兩種呼叫分別稱為「向下呼叫」和「向上呼叫」,統稱為「外部呼叫」。
注意:目前,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檔案 來執行此操作。