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++编写的文件生成动态连接库
public class HelloNative{ public native void greeting();//所有native所修饰的都是本地方法 static{System.loadLibrary("HelloNative");//载入本地库 } public static void main(String[] args){new HelloNative().greeting();// System.out.println(System.getProperty("java.library.path")); }}
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明该方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。 Load动态库:System.loadLibrary(“HelloNative”);加载动态库(我们可以这样理解:我们的方法 greeting()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“HelloNative”是动态库的名字。
javac HelloNative.java
javah HelloNative
命令执行后会在当前目录下生产一个c的头文件,名字为HelloNative.h。内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloNative */ #ifndef _Included_HelloNative#define _Included_HelloNative#ifdef __cplusplusextern "C" {#endif/* * Class: HelloNative * Method: greeting * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv *, jobject); #ifdef __cplusplus}#endif#endif
这个h文件相当于我们在java里面的接口,这里声明了一个 Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致
#include <stdio.h>#include <jni.h>#include "HelloNative.h" JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv * env, jobject obj){ printf("Hello, Native!/n");}
gcc -fPIC -I/home/elton/jdk/include -I/home/elton/jdk/include/linux -shared -o libHelloNative.so HelloNative.c
注意,必须告知编译器jni.h所在的接口位置。linux的动态库都是以lib开头,以.so结尾的,要遵守这个命名规范。-fPIC是告诉编译器生成跟位置无关的动态链接库
命令执行后,会在当前目录生成一个libHelloNative.so的动态链接库文件
java -Djava.library.path=. HelloNative
必须指定java.library.path变量的内容,告诉java你的动态链接库的位置。
或者在命令行上输入
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
这样就不用每次调试的时候都输入-Djava.library.path=.这个参数了。
当你部署的时候,你通过System.out.println(System.getProperty(“java.library.path”));得到你系统的java.library.path位置,然后把你的动态链接库拷贝到这个目录中。我用的是ubuntu 11.04 64位版本,得到的结果是
/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
这样你的动态链接库就永远都会被java访问到了,不用每次指定环境变量了。
觉得文章有用?立即:和朋友一起 共学习 共进步!
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习