C#調用Java方法執行個體詳解_C#教程

來源:互聯網
上載者:User

C#可以直接引用C++的DLL和轉換JAVA寫好的程式。最近由於工作原因接觸這方面比較多,根據實際需求,我們通過一個具體例子把一個JAVA方法轉換成可以由C#直接調用的DLL

C#調用c++

C#調用C++的例子網上很多,以一個C++的具體方法為例。

C++代碼

// 擷取一幀映像資料MVSMARTCAMCTRL_API int __stdcall MV_SC_GetOneFrame(IN void* handle, IN OUT unsigned char *pData , IN unsigned int nDataSize, IN OUT MV_SC_IMAGE_OUT_INFO* pstImageInfo);// 結果資料緩衝的上限#define MV_SC_MAX_RESULT_SIZE (1024*16)// 輸出幀的資訊typedef struct _MV_SC_IMAGE_OUT_INFO_{unsigned short nWidth; // 映像寬unsigned short nHeight; // 映像高unsigned int nFrameNum; // 幀號unsigned int nFrameLen; // 當前幀資料大小unsigned int nTimeStampHigh; // 時間戳記高32位unsigned int nTimeStampLow; // 時間戳記低32位unsigned int nResultType; // 輸出的訊息類型// 根據訊息類型對應不同的結構體unsigned char chResult[MV_SC_MAX_RESULT_SIZE];unsigned int nReserved[8]; // 保留}MV_SC_IMAGE_OUT_INFO C#代碼/// <summary>/// 獲得相機所拍照片/// </summary>/// <param name="handle"></param>/// <returns></returns>[DllImport("MvSmartCamCtrl.dll")]public static extern int MV_SC_GetOneFrame(IntPtr handle, Byte[] pData, int nDataSize, out MV_SC_IMAGE_OUT_INFO pstDevInfo);// 輸出幀的資訊[StructLayout(LayoutKind.Sequential)]public struct MV_SC_IMAGE_OUT_INFO{public short nWidth; // 映像寬public short nHeight; // 映像高public int nFrameNum; // 幀號public int nFrameLen; // 當前幀資料大小public int nTimeStampHigh; // 時間戳記高32位public int nTimeStampLow; // 時間戳記低32位public int nResultType; // 輸出的訊息類型// 根據訊息類型對應不同的結構體[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 * 16)]public MV_SC_RESULT_BCR chResult;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]public int[] nReserved;}

這樣我們把這個DLL放在程式根目錄下,就能實現DLL方法的調用。

C#調用JAVA方法

IKVM.NET是一個針對Mono和微軟.net架構的java實現,其設計目的是在.NET平台上運行java程式。它包含了以下的組件:

用.NET實現的java虛擬機器,java類庫的.NET實現。

致力於在java和.NET之間互動的工具。

程式需求

我們有一個JAVA寫好的Demo,傳的參數是用Gzip進行壓縮傳到伺服器的,代碼如下:

package Demo;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.methods.PostMethod;import org.apache.commons.httpclient.params.HttpClientParams;import com.google.gson.Gson;public class Demo{public static String doPostClient(String json, String url){HttpClient httpClient = new HttpClient();String rval = "";PostMethod postMethod = new PostMethod(url);try{Gson gson = new Gson();InputStream in = new ByteArrayInputStream(objectToByte(json));postMethod.setRequestBody(in);HttpClientParams params = new HttpClientParams();httpClient.setParams(params);httpClient.executeMethod(postMethod);byte[] b = postMethod.getResponseBody();String rtnData = (String) byteToObject(b);rval = gson.toJson(rtnData);} catch (Exception e){rval="erro:"+e.getMessage();} finally{postMethod.releaseConnection();}return rval;}public static byte[] objectToByte(java.lang.Object obj){byte[] bytes = null;ObjectOutputStream oo = null;try{ByteArrayOutputStream out = new ByteArrayOutputStream();GZIPOutputStream gzip = new GZIPOutputStream(out);gzip.write(obj.toString().getBytes("utf-8"));gzip.close();bytes = out.toByteArray();} catch (Exception e){e.printStackTrace();} finally{if (oo != null){try{oo.close();} catch (IOException e){e.printStackTrace();}}}return bytes;}private static java.lang.Object byteToObject(byte[] bytes){String obj = "";ObjectInputStream oi = null;try{ByteArrayInputStream bi = new ByteArrayInputStream(bytes);GZIPInputStream gzipi = new GZIPInputStream(bi);BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gzipi, "UTF-8"));String line;while ((line = bufferedReader.readLine()) != null){obj+=line; }} catch (Exception e){e.printStackTrace();} finally{if (oi != null){try{oi.close();} catch (IOException e){e.printStackTrace();}}}return obj;}}

這個代碼我用C#改寫了,用HttpWebRequest的方式傳到伺服器,伺服器那邊Gzip解壓不了,查了原因是因為Java與C#的Byte類型值範圍不同,我們有兩種解決思路,一種是將這個JAVA做成webservice掛在伺服器上,c#再去調用,第二種就是將這個方法編譯成可由C#直接調用的DLL,由於這個方法功能比較單一,我們選取了後者。

環境配置

IKVM.NET 下載後解壓得到BIN檔案夾中的資料,用於JAR包轉換和基礎DLL。

IKVM.OpenJDK.ClassLibrary.dll用於C#程式接入。

下載地址:https://yunpan.cn/cBHTS5fXsIe9v 訪問密碼 0847。

將IKVM.NET的BIN檔案夾的地址添加到環境變數。

電腦右鍵屬性--進階系統設定--進階--環境變數--在系統變數中找到PATH--將BIN檔案夾的地址添加進去,
在CMD中輸入ikvmc 有協助文檔說明環境配置成功。

Bin檔案夾下的IKVM.OpenJDK.Core.dll,IKVM.Runtime.dll,IKVM.Runtime.JNI.dll和IKVM.OpenJDK.ClassLibrary.dll為公用DLL,所有轉換程式都需引用

轉換步驟

1.確定參考關聯性:

該Demo的結構如下:

Demo.jar 依賴於 commons-httpclient-3.1.jar 和 gson-2.4.jar

commons-httpclient-3.1.jar 依賴於 commons-logging-1.1.3.jar 和 commons-codec-1.6.jar

我們先將gson-2.4.jar,commons-logging-1.1.3.jar,commons-codec-1.6.jar 產生DLL,文法如下:

ikvmc JAR包實體路徑。

win7系統預設產生在C:\Users\Administrator 這個檔案夾下

commons-httpclient-3.1.dll 產生文法如下:

ikvmc commons-httpclient-3.1.jar -r:commons-logging-1.1.3.dll -r:commons-codec-1.6.dll

我們將Demo打包的名字為JavaApi.Demo 這樣產生的 JavaApi.dll 產生文法如下:

ikvmc JavaApi.Demo.jar -r:commons-httpclient-3.1.dll -r:gson-2.4.dll

上面的檔案都是相對應的實體路徑,然後將所有產生的DLL添加到C#項目中引用,包括之前的公用DLL,引用到項目中所有引用的DLL如圖:


這樣就可以直接在程式中使用這個java方法了

Demo.Demo.doPostClient(js, url);

第一個Demo java程式中的package名。

第二個Demo java程式中的class名。

以上所述是小編給大家介紹的C#調用Java方法執行個體詳解的全部敘述,希望對大家有所協助,如果大家想瞭解更多內容敬請關注云棲社區網站!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.