JNI(Java Native Interface),它允许Java代码和其他语言写的代码进行交互。
JNI步骤:
- 创建一个类(MyJni.java)
- javac 编译该类
- javah -jni 产生头文件
- 编写本地代码,实现头文件中定义的方法。
- Run
public class MyJni { static { System.loadLibrary("myjni"); } /* * 使用JNI的关键字native * 这个关键字决定我们那些方法能在我们的C文件中使用 * 只须声明,不必实现 */ public native void sayHi(String name); public static native void add(int num); public static void main(String[] args) { new MyJni().sayHi(null); MyJni.add(100); } }
F:workspaceLearnsrc>javac orgjniMyJni.java
F:workspaceLearnsrc>javah -jni org.jni.MyJni
在 F:workspaceLearnsrc 下生成 org_jni_MyJni.h,代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_jni_MyJni */ #ifndef _Included_org_jni_MyJni #define _Included_org_jni_MyJni #ifdef __cplusplus extern "C" { #endif /* * Class: org_jni_MyJni * Method: sayHi * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_org_jni_MyJni_sayHi (JNIEnv *, jobject, jstring); /* * Class: org_jni_MyJni * Method: add * Signature: (I)V */ JNIEXPORT void JNICALL Java_org_jni_MyJni_add (JNIEnv *, jclass, jint); #ifdef __cplusplus } #endif #endif
编写 jni_MyJniImpl.c,
#include <jni.h> #include "org_jni_MyJni.h" #include <stdio.h> JNIEXPORT void JNICALL Java_org_jni_MyJni_sayHi (JNIEnv *env, jobject obj, jstring name) { printf("From jni_MyJniImpl.c : sayHi. "); const jbyte *str; str = (*env)->GetStringUTFChars(env, name, NULL); if (str == NULL) { printf("the string is null. "); return ; /* OutOfMemoryError already thrown */ } printf("the string is %s. ", str); return; } JNIEXPORT void JNICALL Java_org_jni_MyJni_add (JNIEnv *env, jobject obj, jint num){ printf("From jni_MyJniImpl.c : add. "); return; }
参数1 - JNIEnv自变量——它是指向类型为JNIEnv_的一个特殊JNI数据结构的指针。JNI数据结构的一个元素是指向由JVM生成的一个数组的指针;该数组的每个元素都是指向一个JNI函数的指针。可从固有方法的内部发出对JNI函数的调用,做法是撤消对这些指针的引用(具体的操作实际很简 单)。每种JVM都以自己的方式实现了JNI函数,但它们的地址肯定位于预先定义好的偏移处。
参数2 - 若方法是实例方法,则为jobject,相当于对象本身,即this。若是静态方法,则指向所在类 jclass。
编译生成动态库myjni.dll
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I F:Javajdk1.6.0_25include –I F:Javajdk1.6.0_25includewin32 -shared -o myjni.dll jni_MyJniImpl.c
运行JNI:把编译好的 dll 放到项目根目录,注意不是代码根目录。