當 Java 應用需存取作業系統原生功能(如調整滑鼠速度、變更視窗背景、甚至撰寫遠端控制工具)時,JNI(Java Native Interface)提供橋樑,讓 Java 呼叫 C/C++ 實作的原生程式碼。
class HelloWorld {
public native void displayHelloWorld(); // 宣告原生方法
static {
System.loadLibrary("hello"); // 載入原生庫 hello.dll / libhello.so
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
編譯:javac HelloWorld.java 產生 HelloWorld.class
使用 JDK 工具 javah:
javah HelloWorld
產生 HelloWorld.h,包含 JNI 函式簽名:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
#include
#include "HelloWorld.h"
#include
#include
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) {
printf("Hello world!\n");
MessageBeep(0); // 呼叫 Windows API 發出蜂鳴聲
}
編譯指令(Windows VC++):
cl -I"C:\jdk\include" -I"C:\jdk\include\win32" -LD HelloWorldImp.c -Fehello.dll
Linux/Solaris (GCC):
cc -G -I/usr/local/java/include -I/usr/local/java/include/solaris HelloWorldImp.c -o libhello.so
注意: 動態庫檔名必須與 System.loadLibrary("hello") 參數一致(hello.dll 或 libhello.so)。
java HelloWorld
輸出:
Hello world!
(伴隨系統蜂鳴聲)
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
原因:JVM 找不到動態庫。解決:將 hello.dll 放置於:
.class 同目錄java.library.path:java -Djava.library.path=. HelloWorldnative 關鍵字標記原生方法System.loadLibrary 載入平台相關動態庫javah 自動產生符合 JNI 命名慣例的標頭檔Java_類別名_方法名JNIEnv* 提供 JNI 環境操作介面,第二參數 jobject 對應 Java 物件實例include 與 include/平台 目錄掌握此流程,即可將 Java 擴展至任意原生功能,打破平台限制。