JNI(Java Native Interface),它容許Java代碼和其餘語言寫的代碼進行交互。java
JNI步驟:數組
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:\workspace\Learn\src>javac org\jni\MyJni.java
F:\workspace\Learn\src>javah -jni org.jni.MyJni
在 F:\workspace\Learn\src 下生成 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. \n"); const jbyte *str; str = (*env)->GetStringUTFChars(env, name, NULL); if (str == NULL) { printf("the string is null.\n"); return ; /* OutOfMemoryError already thrown */ } printf("the string is %s.\n", str); return; } JNIEXPORT void JNICALL Java_org_jni_MyJni_add (JNIEnv *env, jobject obj, jint num){ printf("From jni_MyJniImpl.c : add. \n"); return; }
參數1 - JNIEnv自變量——它是指向類型爲JNIEnv_的一個特殊JNI數據結構的指針。JNI數據結構的一個元素是指向由JVM生成的一個數組的指針;該數組的每一個元素都是指向一個JNI函數的指針。可從固有方法的內部發出對JNI函數的調用,作法是撤消對這些指針的引用(具體的操做實際很簡 單)。每種JVM都以本身的方式實現了JNI函數,但它們的地址確定位於預先定義好的偏移處。this
參數2 - 若方法是實例方法,則爲jobject,至關於對象自己,即this。如果靜態方法,則指向所在類 jclass。spa
編譯生成動態庫myjni.dll指針
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I F:\Java\jdk1.6.0_25\include –I F:\Java\jdk1.6.0_25\include\win32 -shared -o myjni.dll jni_MyJniImpl.c
運行JNI:把編譯好的 dll 放到項目根目錄,注意不是代碼根目錄。code