将静态库与JNI链接

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

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

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

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

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

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

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

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

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

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