java 利用jna調(diào)用c#的dll

原文鏈接:http://www.cnblogs.com/wyongbo/p/jnaTest.html

一、需求闡述:

  如果我們的項(xiàng)目利用c#開發(fā),到了開發(fā)后期需要和java組進(jìn)行合作,其中有一部分業(yè)務(wù)邏輯利用c#已經(jīng)code completed,那么我們可能會考慮用java來調(diào)用現(xiàn)成的c#dll實(shí)現(xiàn)需求。前幾天工作上正好遇到這樣一個(gè)問題,于是記下開發(fā)過程。

  當(dāng)然這只是個(gè)假設(shè),具體情況具體分析,個(gè)人認(rèn)為重構(gòu)代碼才是王道……

二、原理說明:

  其實(shí)具體原理我也沒弄太明白,我就根據(jù)自己的理解來說吧,拋磚引玉。

  因?yàn)閏#代碼是托管到.net平臺上的,所以java不能直接調(diào)用c#代碼,于是引入C++中間件,c++項(xiàng)目可以設(shè)置項(xiàng)目為clr公共運(yùn)行時(shí),從而通過引用的方式調(diào)用c#相應(yīng)方法。而jna是可以直接調(diào)用c++生成的dll的,于是大致流程就走通了。c++調(diào)用寫好的c#dll,java再調(diào)用c++生成的dll中間件,大致流程就是這樣了,不過其中有很多坑,下面我會細(xì)說。

三、運(yùn)行平臺:

  系統(tǒng):Windows 10 x64

  開發(fā)工具:Visual Studio 2015/2017(我筆記本和公司電腦安裝不同版本,我都有實(shí)現(xiàn)過) ? MyEclipse2014 ??

  SDK:jdk-x86、jdk-x64 (dll分為x86和x64平臺,和jdk的版本要對應(yīng),同一臺電腦裝兩個(gè)版本的jdk比較煩,我采用的是系統(tǒng)配置jdk32位調(diào)試32位dll,然后myeclipse自帶64位jdk調(diào)試64位dll)

四、準(zhǔn)備工作:

  1、首先準(zhǔn)備上述運(yùn)行平臺,建議選擇和系統(tǒng)位數(shù)一致的jdk(安裝vs、myeclipse或eclipse或sts);

  2、下載jna.jar :JNA下載(下載jna-4.4.0.jar 和 jna-platform-4.4.0)


五、開始CODE

  5.1 生成c#DLL

    5.1.1 以管理員方式啟動vs(項(xiàng)目涉及到注冊com組件,必須以管理員啟動才能完成),新建c#項(xiàng)目

    5.1.2 設(shè)置c#項(xiàng)目

      首先,右鍵剛剛新建的Invoke項(xiàng)目,點(diǎn)擊屬性。


?        繼續(xù)設(shè)置項(xiàng)目屬性。


?        記得保存。

?        然后新建需要被調(diào)用的CSharp類代碼。這里我們新建一些簡單的方法,為了演示效果我們分別對int、string、bool進(jìn)行操作。如圖:

        然后右鍵項(xiàng)目,點(diǎn)擊生成。

        第一步,完成,干得漂亮。

  5.2 生成c++中間件

    5.2.1 新建c++項(xiàng)目并設(shè)置屬性


      項(xiàng)目新建成功,右鍵項(xiàng)目,選擇屬性。


    5.2.2 書寫c++代碼

      添加cpp文件


?          編輯cpp文件

+ View Code

      好了,c++和c#全部工作完成,右鍵生成。

      復(fù)制下dll生成文件全名,一會兒java里面用。


六、編寫java代碼

  6.1 新建java project ,注意選擇和dll平臺一致的jdk。然后將之前下載的兩個(gè)jna的jar加載到項(xiàng)目里面,如圖:

  6.2 ?開始寫java 代碼

+ View Code

  然后我們運(yùn)行:

      哦豁,報(bào)錯了【無效的內(nèi)存訪問】,因?yàn)閖ava找到了c++dll,但是沒找到c#的dll,其中c++dll我們寫的全路徑名,可以直接找到,那么c#的dll怎么找呢。答案是將c#的dll復(fù)制到j(luò)dk的bin目錄下,jvm就能找到了。

      如圖我們將Invoke.dll復(fù)制到j(luò)dk的bin目錄下:

      然后再運(yùn)行:

      nice!對于常用類型中的int、string、boolean都可以順利傳遞了,事實(shí)上其他類型的也可以實(shí)現(xiàn),只要遵循不同語言之間的類型對應(yīng)關(guān)系就可以了,具體的類型關(guān)系可以百度。


七、注意事項(xiàng)

  7.1 java報(bào)錯:Exception in thread "main" java.lang.Error: Invalid memory access

    可能原因:

      1、c#dll沒有復(fù)制到j(luò)dk的bin目錄;

      2、java和c++之間數(shù)據(jù)類型不對應(yīng);

  7.1.2 java報(bào)錯:Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'D:\vs workplace\X86InvokeTest\Release\X86CPPDlls': Native library (win32-x86/D:\vs workplace\X86InvokeTest\Release\X86CPPDlls.dll) not found in resource path ([file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/bin/, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-4.4.0.jar, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-platform-4.4.0.jar])

    可能原因:

      1、c++dll路徑不正確,建議做test時(shí)用絕對路徑,這樣你在c++項(xiàng)目編譯過后不用拷貝便可以在java程序里面直接調(diào)用;

      2、jdk的平臺和c++項(xiàng)目的平臺不匹配,jdk是32位那么c++dll一定也是32位的,64位也同樣;

  7.1.3 windows64位下編譯的32位dll測試失敗,暫時(shí)不清楚是不是64位系統(tǒng)的原因,由于我電腦虛擬機(jī)沒有裝上,就沒有去32位系統(tǒng)上測試了。


================================2018-1-3 17:15:54 更新========================================================

1、提供給測試項(xiàng)目開源地址:

Github測試代碼連接

Github測試代碼連接2

2、怎么確定c#的dll是不是成功復(fù)制到j(luò)dk的bin目錄呢?換言之怎么確定自己的bin目錄在哪里呢?可以在eclipse中運(yùn)行的時(shí)候通過控制臺看到。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • C#調(diào)用Java 將jar轉(zhuǎn)換為dll具體步驟 :下載一個(gè) IKVM 配置好環(huán)境變量 具體操作如下一、將已經(jīng)...
    CrixalisAs閱讀 2,822評論 0 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,366評論 25 708
  • 秋雨如煙化寒涼, 塵風(fēng)褪去碧池裝; 華容漸變楓紅葉, 一瞬披霜盡滄桑。
    月夜秋荷閱讀 412評論 3 15
  • Your hobby Playing video game I love to play video game. ...
    王死彎閱讀 572評論 0 0
  • 1、分析病案時(shí),在分析完每一癥狀,及它的直接原因后,在綜合整個(gè)病案論證推理病因、癥狀、用藥、治療思路時(shí),深感基礎(chǔ)太...
    你的樣子_7af8閱讀 178評論 0 0

友情鏈接更多精彩內(nèi)容