JNI使用说明一、什么是JNIJNI是javanativeinterface的缩写,java毕竟是一个虚拟机上运行的语言,在虚拟机上的所有问题java语言本身完全可以搞的定。但是现在如果我在一个linux版本上修改了内核,加上了我自己写的某些东西,这时候java再怎么厉害也不可能能够调用我写的功能,当然java语言的开发者也非常的了解这一点,作为javaVM的扩展,退出了JNI。至于JNI的其他的说明,可以百度一下,这里就不多说了。二、为什么需要使用JNI在上面的说明中,已经表现了JNI的一种用途,实际上我们可以这样理解JNI的使用场景,当下编程语言很多java/C/C++/python/matlab/R/perl,每一种语言都是各有特点,如果说需要大量的计算那么使用C语言就比较靠谱,如果需要数据的处理,使用python或许是一个不错的选择,如果需要进行数学运算或者需要仿真那么MATLAB绝对是首选,我们一般做系统使用java,这时就可以互补的去操作,如果我们需要使用java访问嵌入式的设备,使用C有时是必选的。这时候使用动态链接库java直接调用,爽爆了。我们简单的列出使用JNI的一些常见的使用场景:1.现在有两个系统,分别是由java和C编写的,如果说需要把这两个联合起来使用的话,必须使用JNI,否则就要重写系统。2.一些复杂的算法,大量计算,加解密,编码解码等需要其他语言协助。3.一些嵌入式设备只能使用类C语言编写的。4.其他语言已经写好了算法,不想重写,希望直接拿来使用的。三、使用JNI的准备前提我这里使用的是jdk1.7.0的版本,工作平台是Ubuntu14.0四、使用流程第一步需要编写java文件,注意需要加载动态链接库,注意:动态链接库在win32平台下是*.dll,在linux平台下是*.so而且System.loadLibrary(Hello);那么动态链接库的名字必须是libHello.so文件而且该文件需要放在一个/lib文件夹下面(就是放在path目录下面)。第二步:javah-jniXXXX生成一个*.h文件,头文件里写着这个native的接口,然后编写一个C/CPP文件实现这个接口就可以了。注意:JNIEXPORTvoidJNICALLJava_JniTest_output(JNIEnv*,jobject);相当于java给C一个参数,然后C返回一个结果,其中JNIEnv*是一个非常重要的值,这里面有着大量的函数可以被我们调用,最常见的就是字符串。由于java内部的数据类型和C中的数据类型有所区别,然后jni.h这个头文件里给出了常用的数据类型的转换map:java中的字符串的编码格式是Unicode,但是C中的字符串的编码格式默认是ASCILL码,这样需要JNIEnv*env,进行操作,可以看一下:第三步:生成动态链接库gcc-shared-I/usr/lib/jvm/java-6-sun-1.6.0.22/include/-I/usr/lib/jvm/java-6-sun-1.6.0.22/include/linux/-I/usr/include/jni_test.c-olibHello.so第一个需要改动的是jdk的include目录和include/linux两个目录的地址第二个要改动的是C文件的名字第三个要改动的是动态链接库的名字:lib+XXX+.so第四步:把这个动态链接库放在/lib文件夹下当然可以不放在这个文件夹下面,可以自行百度。但是这是一个最简单的方法第五步:编译java文件并运行五、简单分析总之,先写一个接口,使用javah生成一个头文件,然后写一个C文件实现这个头文件中的接口,然后编译生成动态链接库,并把生成的动态链接库放到lib文件夹下面,下面这个native的接口就可以自己去调用这个动态链接库了,很方便。唯一的问题是java的平台无关性就此byebye了,因为使用到了本地的动态链接库。六、后续具体的代码编写,可以看看别人写的代码。jstring/jclass这些可以看看jni.h的头文件,看看它们是如何定义的。