一.JNI简介
JNI是Java Native Interface的缩写,它实现了Java与其他语言(主要是C&C++)通信的API。
1.JNI与本地程序进行交互的方式:
(1)使用JNI实现本地方法(native methods),并在Java程序中调用,在本文中,我们主要介绍该方式。
(2)JNI支持一个“调用接口(invocation interface)”,它允许将一个JVM嵌入到本地程序中,本地程序可以链接一个实现了JVM的本地库,然后使用“调用接口”执行Java编写的软件模块。例如,一个用C编写的浏览器可以在一个嵌入式JVM上面执行网上下载下来的applets。
2.JNI的使用场合:
(1)JAVA程序当中的一部分代码对效率要求非常高,如算法计算,图形处理等。
(2)在本地还有一个别的系统,不过他不是Java语言实现的,这个时候你的老板要求你把两套系统整合到一起。
(3)程序当中用到了JAVA API不提供的特殊系统环境才会有的特征。
3.JNI的副作用:
(1)程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。
(2)JNI调用是相当慢的,在实际使用的之前一定要先想明白是否有这个必要。
(3)程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。
二.JNI实例
主要步骤:
(1)编写包含native本地方法的java类
(2)通过javah工具生成C/C++语言的头文件
(3)建立dll项目,使用C/C++语言实现头文件
(4)将(3)中的文件,编译生成*.dll动态链接库,在Linux下则生成*.so可执行的C/C++库
(5)实际执行Java代码去和本地的C/C++代码互相沟通
下面我们仔细讲一讲上述步骤的细节:
1.编写包含native本地方法的java类
<span style="font-size:14px;">public class My {
public native String hello(String arg);
static {
System.loadLibrary("My");
}
public static void main(String[] args){
new My().hello("Hello world!");
}
}
</span>
(1)生命本地方法:我们看到对于方法hello()前面有关键字native,表示这是一个本地(native)方法,并且,并没有具体的java代码实现它,实际上,它仅仅提供了一个供调用的接口,具体的实现交给C/C++实现。
(2)载入动态链接库:再看该类的static代码块,其作用为在初始化过程中载入含有C/C++实现的Java中声明本地方法的动态链接库。
2.通过javah工具生成C/C++语言的头文件
(1) 编译该java文件:javac My.java
(2) 产生头文件: javah -jni My (-jni是默认命令)若是带有包名的,包名与类间用“.”相间隔。此时,我们会看到根路径下会出现一个*.h头文件。
3.建立dll项目,使用C/C++语言实现头文件
在DEV中创建一个dll项目,删除其默认文件,将我们的*.h文件拷入到其路径。用C/C++实现其方法。
//My.cpp
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "My.h"
JNIEXPORT jstring JNICALL Java_My_hello(JNIEnv *env,jobject obj,jstring pString)
{
//从jstring中获取本地方法传递的字符串
const char *nativeString =(*env) ->GetStringUTFChars(env,pString, 0);
printf("%s", nativeString);
return pString;
}
4.将(3)中的文件,编译生成*.dll动态链接库,在Linux下则生成*.so可执行的C/C++库
右键DEV My工程,选择工程属性----》文件/目录----》包含文件目录---》添加 C:\Program Files\Java\jdk1.6.0_10\include和C:\Program Files\Java\jdk1.6.0_10\include\win32 [jdk的目录根据你的安装目录变动]
编译无语法错误的话将会产生:My.dll
5.实际执行Java代码去和本地的C/C++代码互相沟通
将My.dll拷贝至My.class文件所在的目录
CMD中输入:java My
就会看见控制台输出 Hello world!的字段