C# 调用C++ Dll 参数 void* 怎么转换struct

you34 2013-08-14 02:04:14
千辛万苦,经过坛子里的高手指点,用unsafe的写法c#的代码终于能得到c++ dll里传过来的值了(尽管debug的时候还是会有错误,但好歹现在有数据了),现在有个问题dll里有参数是void*,根据类型转换成不同的结构,比如提供的c++客户端例子是这样写的:

RecvDataHandler(const TMsgHead *pAppHead, const void *pData){
switch(pMsgHead->sDataType)
{
case 1:{//pData转成单一结构TStuct1
TStuct1 *p1= (TStuct1 *)pData;
sprintf(p1.data);
....
}
case 2:{//pData转成结构数组TStuct2
THead *pHead = (THead *)pAppHead;
TStuct2 *p2 = (TStuct2 *)pData;
for(i = 0; i < pHead ->nItems; i++)
{
//
sprintf(p2[i].nStatus);
......
}
}

}

我c#这样写

unsafe void RecvDataHandler(ref TMsgHead pAppHead, IntPtr pData)
{
switch (pMsgHead.sDataType)
{
1:{
TStuct1 d1 = new TStuct1 ();
d1 = (TStuct1)Marshal.PtrToStructure(pData, typeof(TStuct1));
logger.Info(d1.data);//能正常得到data值
}
2:{
TStuct2 d = new TStuct2[pMsgHead.nItems];
//这句一直报错
d = (TStuct2[])Marshal.PtrToStructure(pData, typeof(TStuct2[]));
}
}
...全文
753 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
裸奔的蜗牛 2013-08-15
  • 打赏
  • 举报
回复
看不出来...
you34 2013-08-15
  • 打赏
  • 举报
回复
貌似还是结构体定义的问题

 struct TStuct2{
   int	nStatus;
   unsigned int nPre;		
   unsigned int nAsk[10];	
   __int64 iVolume;
   char	chfix[4]
 }
我定义成

   [StructLayout(LayoutKind.Sequential)]
 struct TStuct2{
    [MarshalAs(UnmanagedType.I4)]
    public int	nStatus;

    [MarshalAs(UnmanagedType.I4)]
    public unsigned int nPre;		

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32 * 4)]
    public unsigned int[] nAsk[];
	
    [MarshalAs(UnmanagedType.I8)]
    public Int64 iVolume;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
    public char[] chfix
 }
2个问题: 1、定义__int64返回来的都是0,比如 iVolume字段,我改成long也是0,应该有其他值的 2、dll会很频繁调用这个回调函数写入数据(每秒都有上千笔),程序运行一段时间接收到一部分数据后又 报“该线程尝试读写某个虚拟地址,而它对该地址不具有相应的访问权限”,然后中止。。
tcmakebest 2013-08-15
  • 打赏
  • 举报
回复
不要用数组类型,只能一个一个操作,若有多个,后面的把 intptr 转成 int, 加上结构体大小,再转成 intptr 再获取下一个结构。
jshi123 2013-08-15
  • 打赏
  • 举报
回复
[StructLayout(LayoutKind.Sequential)] internal struct TStuct2 { [MarshalAs(UnmanagedType.I4)] public int nStatus; [MarshalAs(UnmanagedType.U4)] public uint nPre; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10, ArraySubType = UnmanagedType.U4)] public uint[] nAsk; [MarshalAs(UnmanagedType.I8)] public Int64 iVolume; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] chfix; }
you34 2013-08-14
  • 打赏
  • 举报
回复
you34 2013-08-14
  • 打赏
  • 举报
回复
谢谢楼上。还是错误:
jshi123 2013-08-14
  • 打赏
  • 举报
回复
TStuct2[] d = new TStuct2[pMsgHead.nItems]; for (int i = 0; i < pMsgHead.nItems; i++) d[i] = (TStuct2) Marshal.PtrToStructure(pData + Marshal.SizeOf(typeof(TStuct2))*i, typeof(TStuct2));
you34 2013-08-14
  • 打赏
  • 举报
回复
额。。语法是删减代码弄的,
重复创建?
现在运行到
d = (TStuct2[])Marshal.PtrToStructure(pData, typeof(TStuct2[]));

程序就异常中止了
xfyxq 2013-08-14
  • 打赏
  • 举报
回复
除了 switch 语法有点问题、TStuct1和TStuct2重复创建外,没有多大的问题
you34 2013-08-14
  • 打赏
  • 举报
回复
另外这种写法是不是还需要释放资源?因为调用会很频繁

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧