C#與Java交互

C#調(diào)用Java

將jar轉(zhuǎn)換為dll
具體步驟 :下載一個(gè) IKVM 配置好環(huán)境變量 具體操作如下
一、將已經(jīng)編譯后的java中Class文件進(jìn)行打包;打包命令JAR

  1. 此處 java的所有類必須放在一個(gè)Package中,不要使用缺省的包,C#會(huì)找不到類之間的調(diào)用(C#貎似不能引用其它dll里的默認(rèn)namespace里邊的內(nèi)容,所以java文件必須聲明包,以便被轉(zhuǎn)換成命名空間。此外,因?yàn)?java中默認(rèn)訪問權(quán)限的方法會(huì)被轉(zhuǎn)換成internal方法,所以在java中必須將這些方法顯式地聲明為public),需要自己建,我用的是eclipse,寫完程序直接導(dǎo)出成jar文件。

另外現(xiàn)在這個(gè)版本好像不支持Java 圖形界面,反正我調(diào)試時(shí),一旦new一個(gè)控件,C#就說此方法未被實(shí)現(xiàn)什么的。

  1. 也可以使用命令:jar cvf test.jar -C com/ .

其中test.jar為要生成的jar包;com/ . 為指定的當(dāng)前目錄下的文件夾,該文件夾包括子文件夾及class文件;

二、到IKVM官方網(wǎng)站下載IKVM需要的組件 http://www.ikvm.net/

ikvmbin-0.44.0.5.zip

三、設(shè)置路徑

解壓ikvmbin-0.44.0.5.zip ,并將%IKVM_HOME%\bin添加到path中。此處的%IKVM_HOME%是指解壓后ikvm的主目錄。

四、將java的jar包轉(zhuǎn)換為.dll控件

使用的命令:ikvmc -out:IKVM.dll test.jar (整個(gè)操作這個(gè)是主要的。)

其中IKVM.dll為將要生成的.dll控件文件名;test.jar(盡量添加上文件的路徑)為之前打包好的jar包文件。(寫的時(shí)候盡量添加文件的路徑名稱,便于查找生成后的dll文件 )

現(xiàn)在dll文件已經(jīng)成功了,但是后面還有運(yùn)用這個(gè)dll在添加到C#項(xiàng)目中運(yùn)行的時(shí)候可能會(huì)報(bào)錯(cuò)。這些錯(cuò)誤就是缺少一些IKVMxxxx.dll文件,這些文件都在ikvm-0.46.0.1\bin 文件下可以找到。

五、在C#項(xiàng)目中添加所需的控件

1、新建一個(gè)C#.NET項(xiàng)目,首先添加一下必須的DLLs (references中Add reference,然后Browse找到dll)

%IKVM_HOME%\bin\IKVM.OpenJDK.Core.dll

%IKVM_HOME%\bin\IKVM.Runtime.dll

%IKVM_HOME%\bin\IKVM.Runtime.JNI.dll

2、添加已生成的.dll文件

將之前生成好的.dll文件加載到C#項(xiàng)目中

六、測(cè)試

在C#項(xiàng)目中使用java類,其方法同java。首先用using 包名,這樣才能找到類

Java使用jna調(diào)用c#中的dll

一、原理說明:
因?yàn)閏#代碼是托管到.net平臺(tái)上的,所以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中間件,大致流程就是這樣了,不過其中有很多坑,下面我會(huì)細(xì)說。

二、運(yùn)行平臺(tái):

  • 系統(tǒng):Windows 10 x64

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

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

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

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

2、下載jna.jar :JNA下載 (下載jna-4.4.0.jar 和 jna-platform-4.4.0),也可以 本地下載

四、開始CODE

1. 生成c#DLL

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

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

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

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

記得保存。

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

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

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

2. 生成c++中間件

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

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

image

(二)書寫c++代碼

添加cpp文件

編輯cpp文件

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


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

五、編寫java代碼

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

2. 開始寫java 代碼

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

哦豁,報(bào)錯(cuò)了【無(wú)效的內(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!對(duì)于常用類型中的int、string、boolean都可以順利傳遞了,事實(shí)上其他類型的也可以實(shí)現(xiàn),只要遵循不同語(yǔ)言之間的類型對(duì)應(yīng)關(guān)系就可以了,具體的類型關(guān)系可以百度。

六、注意事項(xiàng)

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

可能原因:

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

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

2. java報(bào)錯(cuò):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])

可能原因:

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

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

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

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

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

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