将静态库与JNI链接

chm*_*mod 17 java java-native-interface static-libraries static-linking java-8

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

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

Stu*_*rks 10

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

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

一个重要的区别是静态库的初始化方式.通过调用JNI_OnLoad函数初始化动态库,并通过调用取消初始化JNI_OnUnload.每个动态库都可以拥有自己的这些函数版本.如果有多个静态链接库,显然它们不能都具有这些相同名称的函数.对于名为libnameload/unload函数的静态库是JNI_OnLoad_libnameJNI_OnUnload_libname.

JNI_OnLoad_libname函数必须返回值JNI_VERSION_1_8或更高.如果没有,JVM将忽略静态库.

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

  • @chmod我认为你不能修改预先构建的JDK,因为(我相信)无法将其他静态库链接到可执行文件中.如果从源代码构建,则可能需要使用其他参数或变量设置来破解makefile,以便为链接器命令提供静态库.请参阅OpenJDK中的[vm.make](http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/jdk9-b21/make/linux/makefiles/vm.make),例如,靠近320行和以下. (2认同)
  • 不要忘记让你的`JNI_OnLoad_X`函数返回至少`JNI_VERSION_1_8`,否则将默默忽略库. (2认同)

dka*_*zel 5

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

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

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

  • @little_planet:不,您不能简单地将静态库复制到路径中。新方法仅与那些将 JVM 嵌入到可执行文件中的人相关。 (4认同)