JNI(Java Native Interface)是java对本地方法调用的接口,通过它可以实现对本地方法的调用。比如Windows平台上的Dll,或者Linux,Unix上的os里的方法。
在一下情况下可以考虑使用JNI:
1.希望用更低级、更快的编程语言去实现对时间有严格要求的代码。
2.希望从 Java 程序访问旧代码或代码库。
3.需要标准 Java 类库中不支持的依赖于平台的特性。
下边是一个使用Jni在Windows上实现一个Hello World程序:
首先确保你的机器安装了Jdk,我的本地方法是通过C++实现的,用的是VC++6.0,当然其他工具也可以,只要能生成Dll就可以。
配置JNI:把Jdk目录中include中的所有.h头文件包括include现win32中的头文件拷贝到
vc的include目录中(也可以在Vc的工具->选项->目录中添加路径)。
接下来就可以开始编程了
1。建立一个java文件Native.java,内容如下:
public class Native{
public native void Hello();
static{
System.loadLibrary( "Native" );
}
public static void main(String[] args){
new Native().Hello();
}
}
2。编译这个程序,在上述文件所在目录下用javac Native.java编译此程序,编译后产生一个 Native.class文件 ,再用javah Native编译此程序,编译后产生一个Native.h的头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Native */
#ifndef _Included_Native
#define _Included_Native
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Native
* Method: Hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Native_Hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
至此该测试的java部分已经完成。
3。使用C++做本地方法的实现,在VC++ 中新建工程 Win32 Dynamic-Link Labrary,工程名字起为Native,后边都按照默认。
把上边生成的头文件拷贝到工程的根目录下。新建一个Native.cpp文件,用include引入头文件,再把JNIEXPORT void JNICALL Java_Native_Hello
(JNIEnv *, jobject)拷贝到此文件中,加上话括号,在里边完成方法的实现:
#include"Native.h"
JNIEXPORT void JNICALL Java_Native_Hello
(JNIEnv *, jobject){
cout<<"hello World!";
}
然后编译->全部重建通过后再生成Native.dll。
把生成的dll文件拷贝到Native.class 同一路径下,然后用java Native执行,如果顺利的话可以看到输出“Hello World!”
Helloworld程序到此完成。
从上边的例子可以看到jni实现的一般步骤,其实C/c++也可以调用java方法,这个要通过Invocation API 来实现,不过要比java调用c/c++复杂很多,通过jni其实基本上可以操作任何语言,甚至于汇编,可以通过在c÷÷/c++嵌入汇编代码来实现,我今天早上刚做过这个测试,不过出了点问题,当汇编中不使用中断时测试可以通过,但是一旦汇编中用中断jvm就会出错,这可能是由于汇编的中断破坏了jvm所使用的寄存器和内存空间,现在这个问题我还没有找到解决的办法。
参考:https://www6.software.ibm.com/developerworks/cn/education/java/j-jni/tutorial/index.html