应用场景
在eclipse中使用jni技术,在java工程主类中声明native本地动态链接库函数,并在static静态代码块中加载名为”jni_so_test“的本地动态链接库。
使用javah命令生成本地动态链接库头文件,一般与Java主类的名称相同,我的Java主类名为JNItest,所以生成的头文件为”JNItest.h“。
创建一个名为”jni_so_test“的C Project,将JNItest.h拷贝到”jni_so_test“工程中,并创建实现源文件”JNItest.c“实现这个头文件。这样关于本地链接库的所有开发都可以在这个C工程中了。
运行JNItest Java工程,此时会报错:Exception in thread "main" java.lang.UnsatisfiedLinkError: no jni_so_test in java.library.path。意思是JNItest.java中System.loadLibrary("jni_so_test");执行时找不到C工程”jni_so_test“生成的so动态链接库文件,如下图:
运行项目报错:
下一步我们要配置java.library.path,使得JNItest.java运行时能在java.library.path变量中找到C工程”jni_so_test“中生成的”libjni_so_test.so“动态链接库,配置方法如下:右键Java工程”JNItest“,选择菜单”Build Path——Configure Build Path...“,在弹出配置页面展开”JRE System Library[JavaSE-1.7]“,java版本每人电脑可能不同。双击”Native library location:(None)“,在弹出的”Native Library Folder Configuration“页面,填写动态链接库位置。”External Folder...“意思是打开eclipse当前的workspace文件夹以外的目录,而”Workspace...“选项意思是打开workspace内某个工程的目录。由于我创建了名为jni_so_test的C Project编写本地链接库代码,生成的动态链接库文件在工程下的Debug/libjni_so_test.so,所以目录要配置成”jni_so_test/Debug“。这样我们就可以分开编写动态链接库代码和Java代码了,而且由于java的build path配置了C Project中so文件生成的目录,这样两边编码互不影响,java代码还能实时加载最新的动态链接库。
当然,配置动态链接库的目录看个人需求和习惯而定了。
这里有一点需要特别注意:在jni_so_test工程中生成的so动态链接库文件,命名的方式为”lib+【C工程名称】+.so“,所以在C工程”jni_so_test“生成的动态文件为”libjni_so_test.so“(Windows下为libjni_so_test.dll)。但是在java主类JNItest.java中却不能这么写,因为lib和.so都是JNI自动添加上去的:
所以,System.loadLibrary中的库名称只能填写”jni_so_test“,”lib“前缀JNI会自己加上,并且根据系统不同自动生成后缀,如果是Linux系统,后缀为”.so“,如果是Windows,后缀则自动生成为”.dll“。
换一句话来说,不管是通过Eclipse来生成动态链接库文件,还是通过命令行生成,但是生成的动态链接库文件名称前缀必须是”lib“,不然JNI无法解决。