JNI(Java Native Interface),允许java虚拟机内部运行的java代码能够与其它编程语言编写的应用程序和库进行交互操作。JNI可以理解为Java和本地应用程序之间的中介。
实现JNI的步骤一般包括以下六步:
1.编写java源文件
2.编译java文件
3.用javah -jni命令编译得到头文件
4.本地方法的实现,用非java语言编写程序源文件
5.创建一个共享库,用cl编译器编译
6.执行java程序
举例如下:
1:编写java源文件
声明一个native方法:如果将一个方法作为本地方法,那么必须声明为native,并且不能实现。
Load动态库:System.loadLibrary(“Test”):native方法在java中没有实现,但是我们却直接使用,加载动态库的目的就是引入方法的实现。在这儿注意,Test是动态库的名字,但不要加后缀名。
package jni;
public class TestJni
{
public native void display(String strName);
static {
System.loadLibrary("Test");
}
public static void main(String[] args){
new TestJni().display("Christmas");
}
}
2:编译java源文件
E:\javatest>javac -d . TestJni.java
3:编译得到头文件
E:\javatest>javah -jni jni.TestJni
用javah –jni jni.TestJni编译得到头文件,在当前目录下生成jni_TestJni.h,内容如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_TestJni */
#ifndef _Included_jni_TestJni
#define _Included_jni_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_TestJni
* Method: display
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_jni_TestJni_display
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
该h文件相当于java中的接口,声明了一个JNIEXPORT void JNICALL Java_jni_TestJni_display(JNIEnv *, jobject, jstring)方法,然后在本地方法(C语言或其它语言编写的方法)实现本方法,也就是在C语言程序中方法名必须跟这一致。
4:本地方法的实现
用C语言编写TestJniImp.cpp文件——主要实现.h中的方法
#include <jni.h>
#include "jni_TestJni.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_jni_TestJni_display(JNIEnv *env, jobject arg, jstring inString){
const jbyte* str;
//从inString字符串取得指向字符串UTF编码的指针
str=(const jbyte*)env->GetStringUTFChars(inString,JNI_FALSE);
printf("Hello,%s\n",str);
//通知本地虚拟机本机代码不再需要通过str访问java字符串
env->ReleaseStringUTFChars(inString,(const char*)str);
return;
}
5: 创建共享库
E:\javatest>cl -I"F:\Program Files\Java\jdk1.7.0_45\include" -I"F:\Program Files\Java\jdk1.7.0_45\include\win32" -LD "E:\javatest\TestJniImp.cpp" -FeTest.dll
cl -I"C:\Program Files\Java\jdk1.5.0_12\include" -I"C:\Program Files\Java\jdk1.5.0_12\include\win32" -LD "D:\testJni\TestJniImp.c" -FeTest.dll
该命令的说明:1)"C:\Program Files\Java\jdk1.5.0_12\include"和"C:\Program Files\Java\jdk1.5.0_12\include\win32"对应java安装目录下的include文件夹,之所以加引号是因为路径之间有空格,如果不加引号将会导致路径错误2)"D:\testJni\TestJniImp.c"对应将要编译C程序的路径3)-FeTest.dll,Test与load动态库中的参数一致 4)如果后缀名为.c编译出现一些无法解决的错误,可以试着将其改为.cpp
6:运行java程序
将生成的dll文件放到system32目录下,运行java程序。如果不加入dll文件,将会出现下图界面上面提示的错误。