一個客戶要使用C#調用我們用C++開發的一個動態鏈接庫,本來我沒有C#的開發經驗,就隨便寫了一個例程。以為很簡單就可以搞定,沒想到客戶開發的過程中遇到了不少問題,最困難的就是用C#調用C++接口中的自定義數據類型的數組作為參數的情況了,解決完問題,總結如下。
DLL接口定義如下:
這里pDinCanInfo是有3個DINCAN_INFO元素數組的指針,其中ReadDinCanInfo中的pDinCanInfo需要作為out參數,WriteDinCanInfo需要作為In參數,這兩種使用形式在C#中的調用方法也不太一樣。
C#調用ReadDinCanInfo關鍵代碼如下:
DINCAN_INFO DinInfo = new DINCAN_INFO();
int size = Marshal.SizeOf(typeof(DINCAN_INFO)) * 3;
byte[] bytes = new byte[size];
IntPtr pBuff = Marshal.AllocHGlobal(size);
DINCAN_INFO[] pDInfo = new DINCAN_INFO[3];
if (ReadDinCanInfo(1811422176, pBuff)) //參數一為卡內碼
{
for (int i = 0; i < 3; ++i)
{
IntPtr pPonitor = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(DINCAN_INFO)) * i);
pDInfo[i] = (DINCAN_INFO)Marshal.PtrToStructure(pPonitor, typeof(DINCAN_INFO));
MessageBox.Show("訂餐日期:" + pDInfo[i].iYear + "-"+ pDInfo[i].iMonth + "-"+ pDInfo[i].iDay);
MessageBox.Show("訂餐餐次:" + pDInfo[i].iMeal);
MessageBox.Show("是否取餐:" + pDInfo[i].bTaked);
}
Marshal.FreeHGlobal(pBuff);
MessageBox.Show("讀取訂餐信息成功");
}
C#調用WriteDinCanInfo關鍵代碼如下:
DINCAN_INFO DinInfo = new DINCAN_INFO();
DinInfo.iYear =Convert.ToUInt32( DateTime.Now.Year);
DinInfo.iMonth = Convert.ToUInt32( DateTime.Now.Month);
DinInfo.iDay = Convert.ToUInt32( DateTime.Now.Day);
DinInfo.iType = 1;
DinInfo.iMeal = 1;
DinInfo.bTaked = false;
int size = Marshal.SizeOf(typeof(DINCAN_INFO)) * 3;
byte[] bytes = new byte[size];
IntPtr pBuff = Marshal.AllocHGlobal(size);
DINCAN_INFO[] pDInfo = new DINCAN_INFO[3];
long ptr = pBuff.ToInt64();
for (int i = 0; i < 3; ++i )
{
IntPtr RPtr = new IntPtr(ptr);
pDInfo[i] = new DINCAN_INFO();
pDInfo[i].iYear = Convert.ToUInt32(DateTime.Now.Year);
pDInfo[i].iMonth = Convert.ToUInt32(DateTime.Now.Month);
pDInfo[i].iDay = Convert.ToUInt32(DateTime.Now.Day);
pDInfo[i].iType = Convert.ToUInt32(i);
pDInfo[i].iMeal = Convert.ToUInt32(i);
pDInfo[i].bTaked = false;
Marshal.StructureToPtr(pDInfo[i], RPtr, false);
ptr += Marshal.SizeOf(typeof(DINCAN_INFO));
}
if (WriteDinCanInfo(1811422176, pBuff)) // 參數一為卡內碼
{
MessageBox.Show("寫入訂餐信息成功");
}
代碼看起來比較麻煩,要參考的抄以上代碼了,主要思想就是申請一塊內存,在申請的這塊內存中構建數組對象,然后將這個內存地址作為pDinCanInfo進行調用。兩個函數的區別就是如何將內存按定義的數據結構進行解析的區別。