C#呼叫C++dll,C++中char*與C#型別的對應關係
阿新 • • 發佈:2019-01-28
最近在編寫C#上位機應用程式,需要呼叫C++的dll,期間遇到dll介面庫中char*型別糾結了很久,試過string,StringBuilder,StringBuilder結果都以失敗告終,通過查詢部落格等資料最後找到了救命稻草---IntPtr。例子如下:
C++dll介面函式:
void JT_ReaderVersion(int icomID,char* szReaderVersion,int iRVerMaxLength char* szAPIVersion, int iAPIVerMaxLength);
szReaderVersion和 szAPIVersion引數作為輸出引數需要返回其所在地址上的字串內容。
C#呼叫該介面函式宣告:
[DllImport("JKT135_SD.dll",CharSet=CharSet.Ansi)] //①public static extern void JT_ReaderVersion(int iComID, ref StringBuilder szReaderVersion, int iRVerMaxLength, ref StringBuilder szAPIVersion, int iAPIVerMaxLength); //②public static extern void JT_ReaderVersion(int iComID, ref Byte[] szReaderVersion, int iRVerMaxLength, ref Byte[] szAPIVersion, int iAPIVerMaxLength); //③public static extern void JT_ReaderVersion(int iComID, ref String szReaderVersion, int iRVerMaxLength, ref String szAPIVersion, int iAPIVerMaxLength); public static extern void JT_ReaderVersion(int iComID, IntPtr szReaderVersion, int iRVerMaxLength, IntPtr szAPIVersion, int iAPIVerMaxLength);
其間通過查詢資料試過StringBuilder,Byte[],string如上面方法①②③所示均失敗,提示:有未經處理的異常:0xC0000005:讀取位置0xXXXXXX時發生訪問衝突。
最後嘗試IntPtr型別成功。
注意:訪問時需要先為IntPtr分配記憶體空間,例如:
IntPtr szReaderVersion = Marshal.AllocHGlobal(100); IntPtr szAPIVersion = Marshal.AllocHGlobal(100); JKT135_SDdllInterface.JT_ReaderVersion(int.Parse(JT_ReaderVersion_comboBox.Text), szReaderVersion, int.Parse(iRVerMaxLength_comboBox.Text), szAPIVersion, int.Parse(iAPIVerMaxLength_comboBox.Text));