JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
大致步骤
编写带有native声明的方法的java类
使用javac命令编译所编写的java类
使用javah命令生成扩展名为h的头文件
使用C/C++实现本地方法
将C/C++编写的文件生成动态连接库
1) 编写java程序:
| |
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明该方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。 Load动态库:System.loadLibrary(“HelloNative”);加载动态库(我们可以这样理解:我们的方法 greeting()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“HelloNative”是动态库的名字。
2) 编译
| |
3) 生成扩展名为h的头文件
| |
命令执行后会在当前目录下生产一个c的头文件,名字为HelloNative.h。内容如下:
| |
这个h文件相当于我们在java里面的接口,这里声明了一个 Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致
4) 编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法。
| |
5) 生成动态库
| |
注意,必须告知编译器jni.h所在的接口位置。linux的动态库都是以lib开头,以.so结尾的,要遵守这个命名规范。-fPIC是告诉编译器生成跟位置无关的动态链接库
命令执行后,会在当前目录生成一个libHelloNative.so的动态链接库文件
6) 运行程序
| |
必须指定java.library.path变量的内容,告诉java你的动态链接库的位置。
或者在命令行上输入
| |
这样就不用每次调试的时候都输入-Djava.library.path=.这个参数了。
当你部署的时候,你通过System.out.println(System.getProperty(“java.library.path”));得到你系统的java.library.path位置,然后把你的动态链接库拷贝到这个目录中。我用的是ubuntu 11.04 64位版本,得到的结果是
| |
这样你的动态链接库就永远都会被java访问到了,不用每次指定环境变量了。