【Java】JDK 17 Foreign Function & Memory API 替代 JNI
2023-12-14 21:42:03
当使用Java与本地代码(如C和C++)交互时,一直以来都需要使用JNI(Java Native Interface)来进行繁琐的手动映射。然而,JDK 17引入了Foreign Function & Memory API,为 Java 开发者提供了一种更简单和安全的方式来调用本地函数并操作内存。
Foreign Function & Memory API 的目标是简化 Java 与本地代码的交互过程,并提供更安全的方式来处理本地代码。它允许 Java 程序直接调用本地函数,无需手动编写JNI代码。这使得在 Java 中调用本地函数和操作内存变得更加直观和易于理解。
printf
示例
首先,需要导入相关的类和接口:
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.LibraryLookup;
import jdk.incubator.foreign.MemoryAddress;
import static jdk.incubator.foreign.MemoryAddress.NULL;
然后,加载本地库并查找要调用的函数:
LibraryLookup libc = LibraryLookup.ofDefault();
MemoryAddress printfFn = libc.lookup("printf").orElseThrow();
接下来,定义本地函数的接口和参数:
FunctionDescriptor printfDescriptor = FunctionDescriptor.of(CLinker.C_POINTER, CLinker.C_CHAR, CLinker.C_POINTER);
然后,分配内存并将数据复制到本地内存中:
MemoryAddress formatStr = MemoryAddress.ofUtf8String("Hello, %s!\n");
MemoryAddress nameStr = MemoryAddress.ofUtf8String("World");
接下来,调用本地函数并传递参数:
CLinker.C_POINTER.execute(printfFn, printfDescriptor, formatStr, nameStr);
最后,释放先前分配的内存:
MemoryAddress.free(formatStr);
MemoryAddress.free(nameStr);
这个示例演示了如何使用Foreign Function & Memory API调用本地函数并输出格式化的字符串。
加减乘除示例
首先,导入相关的类和接口:
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.LibraryLookup;
import jdk.incubator.foreign.MemoryAddress;
import static jdk.incubator.foreign.MemoryAddress.NULL;
然后,加载自定义函数库并查找要调用的函数:
LibraryLookup myLibrary = LibraryLookup.ofPath("/path/to/your/library.so");
MemoryAddress addFn = myLibrary.lookup("add").orElseThrow();
MemoryAddress subtractFn = myLibrary.lookup("subtract").orElseThrow();
MemoryAddress multiplyFn = myLibrary.lookup("multiply").orElseThrow();
MemoryAddress divideFn = myLibrary.lookup("divide").orElseThrow();
接下来,定义本地函数的接口和参数:
// 这里假设四个函数的返回类型和参数类型都是整数(CLinker.C_INT)。根据实际情况,可能需要调整这些类型
FunctionDescriptor addDescriptor = FunctionDescriptor.of(CLinker.C_INT, CLinker.C_INT, CLinker.C_INT);
FunctionDescriptor subtractDescriptor = FunctionDescriptor.of(CLinker.C_INT, CLinker.C_INT, CLinker.C_INT);
FunctionDescriptor multiplyDescriptor = FunctionDescriptor.of(CLinker.C_INT, CLinker.C_INT, CLinker.C_INT);
FunctionDescriptor divideDescriptor = FunctionDescriptor.of(CLinker.C_INT, CLinker.C_INT, CLinker.C_INT);
然后,调用本地函数并传递参数:
int result1 = CLinker.C_INT.execute(addFn, addDescriptor, 5, 3);
int result2 = CLinker.C_INT.execute(subtractFn, subtractDescriptor, 8, 2);
int result3 = CLinker.C_INT.execute(multiplyFn, multiplyDescriptor, 4, 6);
int result4 = CLinker.C_INT.execute(divideFn, divideDescriptor, 15, 3);
最后,打印结果:
System.out.println("Addition result: " + result1);
System.out.println("Subtraction result: " + result2);
System.out.println("Multiplication result: " + result3);
System.out.println("Division result: " + result4);
这个示例演示了如何使用Foreign Function & Memory API调用本地函数进行加减乘除运算。
文章来源:https://blog.csdn.net/m0_47406832/article/details/134925011
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!