Java Native Interface(JNI)是Java语言的本地编程接口,是J2SDK的一部分。在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。 标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的 你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的 程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调用他们 在《java核心技术》中,作者提到JNI的时候,建议不到万不得已不要使用JNI技术,一方面它需要你掌握更多的知识才可以驾驭,一方面使用了JNI你的程序就会丧失可移植性。 1.编写java代码 我们在硬盘上建立一个hello目录作为我们的工作目录,首先我们需要编写自己的java代码,在java代码中我们会声明native方法,代码非常简单。如下所示 class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("Hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 注意我们的displayHelloWorld()方法的声明,它有一个关键字native,表明这个方法使用java以外的语言实现。方法不包括实现,因为我们要用c语言实现它。注意System.loadLibrary("Hello")这句代码,它是在静态初始化块中定义的,系统用来装载Hello共享库,这就是我们在后面生成的libHello.so(如果在其他的操作系统可能是其他的形式,比如 window 系统就是libHello.dll) 2.编译java代码 javac HelloWorld.java 生成HelloWorld.class文件 3.创建.h文件 这一步中我们要使用javah命令生成.h文件,这个文件要在后面的c代码中用到,我们运行 javah HelloWorld。这样我们可以看到在相同目录下生成了一个HelloWorld.h文件,文件内容如下 在此我们不对他进行太多的解释。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 4.编写本地实现代码 在这部分我们要用C语言实现java中定义的方法,我们新建一个HelloWorld.c文件,内容如下 #include #include "HelloWorld.h" #include JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!/n"); } 我们在这里包含了文件,这个文件需要我们到拷贝 /usr/java/jdk1.6.0/include/jni.h 和 /usr/java/jdk1.6.0/include/linux/jni_md.h 到 /usr/include 目录下,要不然编译会报错 5.然后编译HelloWorld.o 文件 gcc -fPIC -c HelloWorld.c (这里面需要 加-fPIC 选项 要不然可能会报错) 一个报错的例子: [root@localhost helloJni]# gcc -shared -fPIC -o libHello.so HelloWorld.o /usr/bin/ld: HelloWorld.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC HelloWorld.o: could not read symbols: Bad value collect2: ld 返回 1 6.编译生成动态库 根据刚才生成的HelloWorld.o文件编译 gcc -shared -fPIC -o libHello.so HelloWorld.o 然后把我们编译生成的动态库拷贝到/usr/lib 下面 7.运行java程序 运行java HelloWorld命令,则可在控制台看到Hello world的输出了。