Java 通過 JNI 呼叫 C/C++ 類庫
阿新 • • 發佈:2019-01-29
說明
由於一些涉及到裝置或底層操作的類庫,大多是C或C++語言編寫的,對於Java Web開發者,在涉及到相應的專案中,不可能再去將相應的類庫用Java重寫。這時,就需要通過Java程式碼去呼叫C/C++的類庫來完成工作。
操作環境:
- JDK 1.8.0_45
- Eclipse
- Visual Studio 2013
注意: demo中的檔案路徑需要加以注意!!!
演示實現
整體目標
通過Java呼叫C++程式碼編寫的 *.dll 類庫中封裝的方法,本 Demo 中包含兩個方法,一個是輸出文字資訊,無返回值;一個計算並返回兩個整數之和。
編寫Java介面
package com.daniel;
/**
* JNI 測試類 JNI_Test.java
* @author PeiXQ
*/
public class JNI_Test {
/**
* 列印文字
* @param mess
*/
public native void sendMess(String mess);
/**
* 計算數值和
* @param a
* @param b
* @return
*/
public native int plusNum(int a,int b);
}
編寫完成後,生成 .class 檔案。
生成 *.h 標頭檔案
進入 cmd
命令列,使用上一步生成的 .class 檔案,利用 jdk 的 javah 命令生成 *.h 標頭檔案。
# javah
# -classpath :E:\JNI_Java_Pro\bin 為.class 檔案所在的根路徑
# .class 檔案的完整路徑為E:\JNI_Java_Pro\bin\com\daniel\JNI_Test.class
# -d : E:\tmp\JNI 輸出 *.h 標頭檔案的路徑
# -jni : 生成JNI樣式的包標頭檔案,可以理解成 *.class 檔案的 包路徑+類名
#
# 此處比較詭異的是,-classpath 必須得是*.class 的包路徑檔案的上一級;
# -jni 必須是*.class 檔案的 包路徑+類名,否則會報錯。
javah -classpath E:\JNI_Java_Pro\bin -d E:\tmp\JNI -jni com.daniel.JNI_Test
編寫C++程式碼
建立一個C++專案
設定應用型別為 dll
將 jdk 目錄下的 jni.h 、 jni_md.h 以及之前生成的 com_daniel_JNI_Test.h 放入專案根路徑下的 include 資料夾 (需自己建立資料夾)
新增專案包含目錄,將上一步建立的 include 資料夾包含進專案。
建立 test_jni.cpp 檔案,並編寫 c++ 程式碼實現,其中的方法頭,可以從 com_daniel_JNI_Test.h 中拷貝。
生成C++dll
執行C++專案的生成按鈕,並在生成路徑下找到生成的 dll 檔案(本文為 jni_gen.dll)。
Java呼叫C++ dll
將生成的 *.dll 新增到Java專案的 Native Library 中,如使用Eclipse,如下圖:
修改最初的 JNI_Test.java 的程式碼,呼叫 dll 中的方法,可看到最下方輸出的執行結果。