在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一个客户要使用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进行调用。两个函数的区别就是如何将内存按定义的数据结构进行解析的区别。 |
请发表评论