前言
最近在做一個通過java程式呼叫c++動態語言庫,在網上百度,谷歌找了諸多例子,還是屢試不爽。經過一番折騰還是披荊斬棘,創出一條道路。希望分享給正在迷茫的朋友們...
使用的環境
spring boot + gradle
JNI介紹
JNI全拼是Java Native Interface,中文意思為Java本地呼叫。JNI標準是Java平臺的一部分,它允許java和其他語言的程式碼進行互動。JNI開始是為了本地已經編譯好的語言,尤其是C和C++而設計的,我們也可以使用JNI和其他語言進行溝通,我們只要呼叫約定受支援了就可以了。
JNI vs JNA
載入流程
使用jni和jna的區別這裡便不再多說。這裡我使用的是jna的方式。不多說,直接擼程式碼,首先在依賴檔案中加入相關jar包。
compile group: 'com.sun.jna', name: 'jna', version: '3.0.9'
windows環境
-
定義好
java
需要呼叫的本地方法,即native
EastmzGame.class
/** * get game result from third * @return */ public native String getGameResult(); 複製程式碼
-
生成
.class
編譯檔案在類檔案的當前目錄執行,這裡加入了字元,防止亂碼。
javac -encoding utf-8 EastmzGame.java
-
生成
.h
標頭檔案在
src.main.java
目錄下執行javah -classpath . -jni com.bsmao.task.jni.EastmzGame
-
再由
vc
編譯工具將.h
檔案實現並且編譯出.dll
檔案,linux為.so
檔案。將
我這裡是放到了resources下面.dll
檔案放入到專案中或者放到e盤中
- java中再呼叫
.dll
檔案
static {
try{
String path = ResourceUtils.getURL("classpath:jniLibs/GetData.dll").getPath();
System.load(path);
//System.load("E:/bsmao/dll/MFCLibrary11.dll"); //e盤的絕對地址
}catch (Exception e){
e.printStackTrace();
}
}
複製程式碼
-
測試呼叫結果
這是經過處理過的資料
linux環境
定義本地方法:
本文是指定路勁讀取so檔案(和so檔案生成的檔案路徑保持一致)
編譯.class
生成.h
,.c
檔案
將上面兩個檔案傳入到linux指定資料夾下
/usr/local/bsmao/lib
sudo cc -I /usr/local/bsmao/java/jdk1.8.0_162/include/linux -I /usr/local/bsmao/java/jdk1.8.0_162/include/ -I /usr/local/bsmao/lib/ -fPIC -shared -o libEastmzGame.so com_bsmao_task_jni_EastmzGame.c
複製程式碼
生成出so檔案
呼叫方式和windows一樣
EastmzGame eastmzGame = new EastmzGame();
byte[] res = eastmzGame.ElevenAgreement();
複製程式碼
測試結果
如果覺得有幫助,請打賞...(^_^ *** ^_^)