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

Java 調用 C/C++ 生成的 DLL 完整教學 (JNI 實戰)

     編輯:Java 相關知識

前言

Java 原生介面 (JNI) 讓 Java 程式能夠呼叫 C/C++ 編寫的本地程式碼,這對於效能敏感模組、硬體驅動或既有程式庫整合至關重要。本文將詳細示範從建立 Java 類別、產生 C++ 標頭檔、在 Visual Studio 建立 DLL 專案,到最終在 Java 中載入並呼叫的完整流程。

一、 產生 C++ 標頭檔

1. 編寫 Java 類別

首先建立一個包含 native 方法的 Java 類別:

public class Main {
    public native static int getStrNum(byte[] str, int strLen);
}

2. 使用 javah 產生標頭檔

開啟命令提示字元,切換至 Main.java 所在目錄,依序執行:

javac Main.java
javah Main

執行完成後會在目錄下產生 Main.h,其中包含 JNI 所需的函式原型宣告。

二、 在 Visual Studio 建立 DLL 專案

1. 建立專案並設定屬性

  • 新建專案:選擇 Win32 Console Application,名稱設為 MakeDLL,勾選 Empty project。
  • 修改專案屬性:
    • General > Configuration Type:改為 Dynamic Library (.dll)。
    • C/C++ > General > Additional Include Directories:加入 JDK 的 include 路徑,例如:
      • C:\Program Files\Java\jdk1.8.0_XXX\include
      • C:\Program Files\Java\jdk1.8.0_XXX\include\win32

      (請依實際 JDK 安裝路徑調整)

2. 加入標頭檔與實作原始碼

將產生的 Main.h 加入專案。新增 main.cpp 並實作 JNI 函式:

#include "Main.h"
#include <string.h>

JNIEXPORT jint JNICALL Java_Main_getStrNum(JNIEnv *env, jclass cls, jbyteArray str, jint strLen) {
    jbyte *buffer = (*env)->GetByteArrayElements(env, str, 0);
    buffer[strLen] = '\0'; // 確保字串結尾
    jint len = strlen((char*)buffer);
    (*env)->ReleaseByteArrayElements(env, str, buffer, 0); // 釋放資源
    return len;
}

注意:實際專案中務必呼叫 ReleaseByteArrayElements 避免記憶體洩漏。

3. 編譯產生 DLL

按 F7 建置方案,輸出目錄下將產生 MakeDLL.dll。

三、 Java 中載入並呼叫 DLL

1. 放置 DLL 檔案

將 MakeDLL.dll 複製到 Java 類別檔相同目錄,或設定 java.library.path 指向 DLL 所在資料夾。

2. Java 程式碼範例

public class Main {
    static {
        System.loadLibrary("MakeDLL"); // 載入 DLL,不需副檔名
    }

    public native static int getStrNum(byte[] str, int strLen);

    public static void main(String[] args) {
        Main instance = new Main();
        String str = "haha";
        int num = instance.getStrNum(str.getBytes(), str.length());
        System.out.println("字串長度: " + num); // 輸出 4
    }
}

四、 關鍵概念補充:參數傳遞與資料交換

  • 基本型別 (int, boolean 等):直接從 JNI 函式參數列表取得。
  • 陣列/物件:必須透過 JNIEnv 指標操作。例如 GetByteArrayElements 取得陣列指標,SetByteArrayRegion 回寫資料。
  • 記憶體管理:Get 系列函式通常會複製或釘住記憶體,用畢必須呼叫對應的 Release 函式。

總結

透過 JNI 整合 C/C++ 程式庫雖然增加了部署複雜度,但能發揮原生程式碼的高效能優勢。掌握標頭檔產生、專案設定、資料轉換與記憶體管理四大核心步驟,即可順利完成 Java 與本地程式碼的互操作。

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