最近在研究使用Java呼叫DLL,由於Java與.NET都是在各自的VM上執行的程式,因此要互相調用對方的api有點困難,查詢到到許多方案例如JNBridge、Javonet等套件都能夠達到此需求,可惜這些套件都需要付授權費用,參考如下;
不過仍然有開源版的套件可使用,這次使用的便是jni4net:
此套件基本上會解析欲呼叫的DLL檔案 -> 生成對應的Bridge程式並重新compile ->接著在專案中呼叫build出的程式即可達到在Java中呼叫.NET DLL的需求,步驟如下;
1. 首先我們要有一隻要呼叫的.NET DLL,不論是自行撰寫或是用第三方DLL都可以,撰寫一支程式如下;
此程式是一個很簡單回傳String字串方法,建置此專案後得到JniForNetDemo.dll,接著準備使用jni4net進行Proxy相關函式庫的產生,如圖:
將DLL檔放入此資料夾後,先編輯proxygen.exe.config如下;
接著開啟CMD命令提示字元,輸入指令proxygen.exe JniForNetDemo.dll C:\test2\
執行完畢, 會在 C:\test2\內看到2個目錄, 2個檔案:
clr\
jvm\
build.cmd
JniForNetDemo.proxygen.xml
接著到該目錄去執行build.cmd,會分別compile出JniForNetDemo.j4n.dll 與 JniForNetDemo.j4n.jar,如果有發生錯誤,通常是javac或是csc這兩組編譯器抓不到,請確定系統變數path有設定正確路徑,完成後將
JniForNetDemo.dll,
JniForNetDemo.j4n.dll,
jni4net.n-0.8.8.0.dll,
jni4net.n.w64.v40-0.8.8.0.dll
加入要使用的webapp src路徑底下(或是你其他自定義的路徑底下也可)
至於 jni4net-0.8.8.0-bin\lib\ 裡的
jni4net.n.w32.v20-0.8.8.0.dll,
jni4net.n.w32.v40-0.8.8.0.dll,
jni4net.n.w64.v20-0.8.8.0.dll,
jni4net.n.w64.v40-0.8.8.0.dll
四個檔案要選哪一個, 就要看當初建 C# 專案時, 是選什麼 Framework, 以及是在 32或是64 位元環境執行.
接著便可以來撰寫一支呼叫用的Java程式,如下;
接著執行該程式,若有成功回傳字串,那就完成了Java調用.NET的功能了!
需要注意的是這種寫法若重新redeploy project的話,會發生java.lang.unsatisfiedlinkerror native library already loaded in another classloader這個錯誤
原因是redeploy時程式不會去將jni4net做資源回收重新載入,所以會發生不能重複載入的情形,解決方案仍在研究當中;
參考資料:
http://yilinliu.blogspot.tw/2015/04/cjava-jni4net-javac.html
http://stackoverflow.com/questions/1030792/dll-already-loaded-in-another-classloader