JNI (Java Native Interface) 是 Java 平台標準功能,彌補「跨平台」與「平台特有功能」間的鴻溝。讓 Java 應用在跨平台優勢下,仍能呼叫 C/C++ 動態庫(.so/.dll),發揮原生效能或存取硬體/系統 API。

package com.magc.jni;
public class HelloWorld {
static {
System.loadLibrary("Hello"); // 載入 libHello.so
}
public native void DisplayHello(); // 原生方法宣告
public static void main(String[] args) {
new HelloWorld().DisplayHello();
}
}
javac ./com/magc/jni/HelloWorld.java
產生 HelloWorld.class。
javah -jni com.magc.jni.HelloWorld
產生 com_magc_jni_HelloWorld.h:
/* DO NOT EDIT - machine generated */
#include
#ifndef _Included_com_magc_jni_HelloWorld
#define _Included_com_magc_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_magc_jni_HelloWorld_DisplayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
關鍵點:
Java_包名_類別名_方法名(點號換底線)。JNIEnv* 提供 JNI 函數表指標,jobject 對應 Java 這個實例。#include。#include
#include "com_magc_jni_HelloWorld.h"
#include
JNIEXPORT void JNICALL Java_com_magc_jni_HelloWorld_DisplayHello
(JNIEnv *env, jobject obj) {
printf("From jni_helloworldImpl.cpp :");
printf("Hello world ! \n");
return;
}
方法名稱、簽名必須與標頭檔完全一致。
g++ -shared -I /usr/lib/jvm/java-6-openjdk/include \
jni_helloworldImpl.cpp -o libHello.so
產生 libHello.so(Linux 慣例 lib 前綴 + 類別庫名)。
java -Djava.library.path=. com.magc.jni.HelloWorld
輸出:
From jni_helloworldImpl.cpp :Hello world !
System.loadLibrary("Hello") 會依平台尋找 libHello.so (Linux) 或 Hello.dll (Windows)。-Djava.library.path 指定動態庫搜尋路徑。