首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

使用 VC++ 6.0 實作 JNI 完整範例教學

     編輯:關於VC++

前言

Java Native Interface (JNI) 是 JDK 的核心組件,提供 Java 程式呼叫本地原生代碼(如 C/C++、組合語言)的標準介面。透過 JNI,運行於 JVM 上的 Java 代碼能夠操作系統級別的函式庫,甚至將 JVM 嵌入原生應用程式中,實現跨平台的無縫整合。本文將以具體範例,詳細示範如何使用 Visual C++ 6.0 完成 JNI 開發的全流程。

實作目標

在 Java 中呼叫 Windows API 的 MessageBox 函式,並傳遞字串參數顯示於對話方塊中。這將展示 Java 如何突破語言限制,直接調用作業系統原生功能。

Step 1:定義包含 Native 方法的 Java 類別

首先建立 WinMsgBox.java,宣告需由本地代碼實作的 showMsgBox 方法:

// WinMsgBox.java
package edu.netcom.jni;

public class WinMsgBox {
    static {
        System.loadLibrary("WinMsgDll"); // (1) 載入動態連結庫
    }
    public native void showMsgBox(String str); // (2) 宣告 native 方法
}

關鍵點說明:

  • (1) WinMsgDll 為 DLL 檔名(不含副檔名),JVM 會依平台自動補全(Windows 為 .dll,Solaris 為 .so)。DLL 必須置於 java.library.path 指定的目錄,常見路徑包含 Windows\system32、JDK bin 目錄、或主類別所在的當前目錄。
  • (2) native 關鍵字標示此方法由本地代碼實作。

Step 2:編譯 Java 原始碼

執行指令:

javac -d . WinMsgBox.java

將於當前目錄產生 edu\netcom\jni\WinMsgBox.class。

Step 3:產生 JNI 標頭檔

使用 javah 工具生成 C/C++ 標頭檔:

javah -jni edu.netcom.jni.WinMsgBox

產生 edu_netcom_jni_WinMsgBox.h,檔名規則為「套件名_類別名」,底線分隔。標頭檔內容包含 JNI 函式原型:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class edu_netcom_jni_WinMsgBox */
#ifndef _Included_edu_netcom_jni_WinMsgBox
#define _Included_edu_netcom_jni_WinMsgBox
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class: edu_netcom_jni_WinMsgBox
 * Method: showMsgBox
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_edu_netcom_jni_WinMsgBox_showMsgBox
  (JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

重點解析:

  • jni.h 位於 JDK include 目錄。
  • 簽名 (Ljava/lang/String;)V 表示參數為 String、回傳 void。
  • JNI 函式命名規則:Java_套件名_類別名_方法名。所有 native 方法會自動增加兩個參數:JNIEnv*(JNI 環境指標)與 jobject(呼叫物件參考)。
  • Java 資料類型對應至 jni.h 定義的本地類型(如 jstring、jint 等)。

Step 4:以 VC++ 6.0 實作並編譯 DLL

  1. 建立專案:File → New → Projects 選擇 Win32 Dynamic-Link Library,專案名稱設為 WinMsgDll(需與 Step 1 一致),選擇 An empty DLL project。
  2. 設定 Include 路徑:Tools → Options → Directories 新增 JDK 的 include 與 include\win32 目錄(如 D:\J2SDK1.4.2_03\INCLUDE)。
  3. 將 Step 3 產生的 edu_netcom_jni_WinMsgBox.h 複製至專案目錄並加入專案。
  4. 新增 WinMsgDll.cpp 實作本地方法:
#include "windows.h"
#include "edu_netcom_jni_WinMsgBox.h"

JNIEXPORT void JNICALL Java_edu_netcom_jni_WinMsgBox_showMsgBox
(JNIEnv *env, jobject obj, jstring str) {
    const char *msg;
    msg = env->GetStringUTFChars(str, 0);      // 將 jstring 轉為 UTF-8 C 字串
    MessageBox(NULL, msg, "Java invoke", MB_OK); // 呼叫 Windows API
    env->ReleaseStringUTFChars(str, msg);      // 釋放資源
}
  1. 編譯產生 WinMsgDll.dll,並複製至 Step 1 指定的庫搜尋路徑(建議與測試類別同目錄)。

關鍵補充:匯出函式的穩健做法

JNI 使用 JNIEXPORT(展開為 __declspec(dllexport))匯出函式,但編譯器可能產生修飾名稱導致找不到符號。建議額外提供 .def 模組定義檔強制指定匯出名稱:

LIBRARY "WinMsgDll"
DESCRIPTION 'message Windows Dynamic Link Library'
EXPORTS
Java_edu_netcom_jni_WinMsgBox_showMsgBox

Step 5:撰寫測試程式驗證

// TestJNI.java
import edu.netcom.jni.WinMsgBox;

public class TestJNI {
    public static void main(String[] args) {
        WinMsgBox box = new WinMsgBox();
        box.showMsgBox("Wonderful!!");
    }
}

編譯執行後,Windows 訊息方塊將跳出顯示「Wonderful!!」,標誌著 JNI 整合成功。

實戰經驗總結

  1. 全鏈路一致性:Java 類別 → 標頭檔 → DLL 檔名 → 載入路徑,任何一環變更皆需重跑全部流程。
  2. DLL 放置位置:務必確認 java.library.path 包含 DLL 所在目錄,否則會拋出 UnsatisfiedLinkError。
  3. 字串處理:使用 GetStringUTFChars/ReleaseStringUTFChars 配對管理記憶體,避免洩漏。

掌握此流程,即可讓 Java 應用程式輕鬆呼叫平台專屬的高效能原生代碼,發揮「Write Once, Run Anywhere」與系統級效能並重的優勢。

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