首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JNI 開發入門:從 Java 呼叫 C/C++ 原生庫的完整範例

     編輯:Java 相關知識

前言:為什麼需要 JNI?

當 Java 應用需存取作業系統原生功能(如調整滑鼠速度、變更視窗背景、甚至撰寫遠端控制工具)時,JNI(Java Native Interface)提供橋樑,讓 Java 呼叫 C/C++ 實作的原生程式碼。

完整開發步驟

1. 撰寫 Java 類別宣告原生方法

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

2. 產生 C/C++ 標頭檔

使用 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

3. 實作 C/C++ 原生程式碼並編譯為動態庫

#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)。

4. 執行驗證

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=. HelloWorld
  • 或放入系統 PATH 環境變數目錄

關鍵點總結

  1. native 關鍵字標記原生方法
  2. System.loadLibrary 載入平台相關動態庫
  3. javah 自動產生符合 JNI 命名慣例的標頭檔
  4. JNI 函式命名規則:Java_類別名_方法名
  5. 第一參數 JNIEnv* 提供 JNI 環境操作介面,第二參數 jobject 對應 Java 物件實例
  6. 平台編譯選項需包含 JDK 的 include 與 include/平台 目錄

掌握此流程,即可將 Java 擴展至任意原生功能,打破平台限制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved