将静态库与 JNI 链接

Java 8 之前的 Java 版本要求本机代码位于共享库中,但我已经读到,在 Java 8 中,可以将静态链接库与 JNI 一起使用。我搜索了示例,但找不到任何示例。

如何将 JNI 库静态链接到我的 Java 应用程序中?


答案 1

Java SE 8 规范已更改为支持静态链接,静态链接在 JDK 中实现。这在 System.loadLibrary 的规范中简要提到过。它所引用的 JNI 规范的各部分在这里这里

本机方法签名和数据类型对于静态和动态链接方法相同。但是,您可能必须破解JDK makefiles才能使其静态链接您的库。

一个显著的区别是静态库的初始化方式。动态库通过调用函数进行初始化,并通过调用 来取消初始化。每个动态库都可以有这些函数的自己版本。如果有多个静态链接的库,显然它们不能都具有具有这些相同名称的函数。对于名为加载/卸载函数的静态库,函数为 和 。JNI_OnLoadJNI_OnUnloadlibnameJNI_OnLoad_libnameJNI_OnUnload_libname

该函数必须返回值或更高。否则,JVM 将忽略静态库。JNI_OnLoad_libnameJNI_VERSION_1_8

基本上,如果调用 ,系统会在正在运行的可执行映像中查找函数,如果找到该函数,则假定该库是静态链接的,并且在正在运行的映像中搜索其本机方法。如果未找到,则通常搜索和加载动态库,并且从动态库中链接本机方法。System.loadLibrary("foo")JNI_OnLoad_fooJNI_OnLoad_foo


答案 2

根据您在评论中链接到的JEP 178,您不必做任何不同的事情。 现在将同时加载动态库和静态库。System.loadLibrary

无需更改现有 Java 代码即可使用静态本机库,而不是动态本机库。特别是对 System.loadLibrary(“foo”) 形式的方法调用应该能够加载 “foo” 库,而不管该库是以静态形式还是动态形式提供。

您可能只需要确保正确设置java.library.path。


推荐