最近在編寫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));