使用OpenJDK的JEP 454从Java访问本机C函数:外部函数和内存 API
Java 的稳健性和跨平台功能使其成为企业应用程序的主力。不过,在有些情况下,Java 应用程序需要与 C 或 C++ 等语言编写的本地库进行交互。Java 本地接口(JNI)一直是满足此类需求的传统解决方案,但它也有自身的复杂性和性能开销。OpenJDK 的 JEP 454 旨在提供一种更直接、更高效的替代方案。
这个 API 是 Panama 项目的一部分,旨在提高 Java 与本地代码交互的能力。在本文中,我们将通过一个简单的示例来演示如何使用 JEP 454 从 Java 程序中调用 C 函数。
需要注意的是,该 JEP 仍处于预览模式。要试用它,您需要 JDK 22。您可以使用 SDKMan 在系统中轻松安装 JDK 22。
JEP 454 有哪些内容?
Java 增强提案 (JEP) 454 旨在引入外来函数与内存 API,简化 Java 与本地代码之间的交互。API 由两个主要部分组成:
- 外来函数接口(FFI):使 Java 程序能够轻松调用本地函数,抽象出 JNI 所需的大量模板代码。
- 内存访问 API:提供一套与本地内存交互的工具,包括内存分配、取消分配和本地数据结构操作等功能。
JEP 454 的设计具有很高的性能,并包含各种安全检查,以防止缓冲区溢出等常见隐患。在大多数使用情况下,它将取代 JNI,为访问本地库和管理本地内存提供更高效、更安全的方法。
创建 C 语言库
首先,让我们创建一个包含两个整数相加的简单函数的 C 程序。代码如下
include <stdio.h> |
编写代码后,将其保存在名为 addition.c 的文件中。要将其编译为共享库,请导航到文件所在目录并运行以下命令:
gcc -shared -o libaddition.so -fPIC addition.c
该命令将 C 代码编译成名为 libaddition.so 的共享库,以便 Java 程序访问。
编写 Java 程序
接下来,让我们编写一个 Java 程序,使用外来函数和内存 API 调用 C 库中的 add 函数。Java 代码如下:
import java.lang.foreign.*; |
将 "libaddition.so "替换为已编译 C 语言库的实际路径。
运行 Java 程序
要编译并运行 Java 程序,请使用以下命令:
java --source 22 --enable-preview Main.java
结果:
sum = 3
结论
OpenJDK 的 JEP 454 为 JNI 与本地代码的交互提供了一个前景广阔的替代方案。通过提供更简单、更安全、更高效的应用程序接口,它有可能彻底改变 Java 开发人员与本地库和内存的工作方式。