千辛万苦,经过坛子里的高手指点,用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[]));
            }     
    }

解决方案 »

  1.   

    除了 switch 语法有点问题、TStuct1和TStuct2重复创建外,没有多大的问题
      

  2.   

    额。。语法是删减代码弄的,
    重复创建?
    现在运行到
      d = (TStuct2[])Marshal.PtrToStructure(pData, typeof(TStuct2[]));
    程序就异常中止了
      

  3.   

    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));
      

  4.   

    貌似还是结构体定义的问题 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会很频繁调用这个回调函数写入数据(每秒都有上千笔),程序运行一段时间接收到一部分数据后又
        报“该线程尝试读写某个虚拟地址,而它对该地址不具有相应的访问权限”,然后中止。。  
      

  5.   

    [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;
    }
      

  6.   

    不要用数组类型,只能一个一个操作,若有多个,后面的把 intptr 转成 int,
    加上结构体大小,再转成 intptr 再获取下一个结构。