Java 8及其以上版本允许使用静态链接库(static linked libraries)来使用JNI,不再要求本地代码必须在共享库中。但是,在Java 8之前的版本需要将本地代码打包成共享库。我查找了一些示例,但没有找到相关的内容。
如何将JNI库静态链接到Java应用程序中呢?
Java 8及其以上版本允许使用静态链接库(static linked libraries)来使用JNI,不再要求本地代码必须在共享库中。但是,在Java 8之前的版本需要将本地代码打包成共享库。我查找了一些示例,但没有找到相关的内容。
如何将JNI库静态链接到Java应用程序中呢?
JNI_OnLoad
函数来初始化动态库,并通过调用JNI_OnUnload
来反初始化。每个动态库都可以拥有自己版本的这些函数。如果有多个静态链接库,那么它们都不能拥有这些相同名称的函数。对于名为libname
的静态库,加载/卸载函数是JNI_OnLoad_libname
和JNI_OnUnload_libname
。
JNI_OnLoad_libname
函数必须返回JNI_VERSION_1_8
或更高版本的值。如果没有,JVM将忽略此静态库。System.loadLibrary("foo")
,系统会在运行的可执行映像中查找函数JNI_OnLoad_foo
,如果找到它,则假定该库被静态链接,并且在运行映像中搜索其本机方法。如果未找到JNI_OnLoad_foo
,则会发生通常的动态库搜索和加载,并从找到的动态库链接本机方法。JNI_OnLoad_X
函数至少返回 JNI_VERSION_1_8
,否则该库将被静默忽略。 - lesenkSystem.loadLibrary
现在将同时加载动态和静态库。Java 8的增强功能https://openjdk.java.net/jeps/178是为JVM而设计的。
给定两个文件:
javac Main.java
javah Main
gcc -c Main.c
gcc -c Main.c -I /home/dx/.sdkman/candidates/java/current/include/linux -I /home/dx/.sdkman/candidates/java/current/include
gcc -shared -o libnative.so Main.o
ar -cvq libnative.a Main.o
java -Djava.library.path=. Main
结果:
libnative.so
执行成功libnative.a
执行失败这证明 178 是针对 JVM 的。
参考文献:
-Djava.library.path
选项是专门用于指定在运行时使用JNI加载的动态/共享库的路径。 - undefined