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方法執行個體詳解的全部敘述,希望對大家有所協助,如果大家想瞭解更多內容敬請關注云棲社區網站!