小弟在编写一个简单界面,使用C#,导入一个C++的Dll
C++的Dll这样声明的
//定义CAN信息帧的数据类型。
typedef  struct  _VCI_CAN_OBJ{
UINT ID;
UINT TimeStamp;   //时间标识
BYTE TimeFlag; //是否使用时间标识
BYTE SendType; //发送标志。保留,未用
BYTE RemoteFlag; //是否是远程帧
BYTE ExternFlag; //是否是扩展帧
BYTE DataLen;
BYTE Data[8];
BYTE Reserved[3]; //保留
}VCI_CAN_OBJ,*PVCI_CAN_OBJ;函数调用是这样的:
DWORD __stdcall VCI_Receive(DWORD DevType,DWORD DevIndex,DWORD CANIndex,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime);给的C++例子是这样调用:VCI_CAN_OBJ pCanObj[200];
NumValue=VCI_Receive(dlg->m_DevType,dlg->m_DevIndex,kCanIndex,pCanObj,200,0);函数返回的是总共接收了多少个帧(结构体),然后根据返回的数量取得结构体内的数据.
我在C#中是这样处理的:
 public struct VCI_CAN_OBJ
    {        /// UINT->unsigned int
        public uint ID;        /// UINT->unsigned int
        public uint TimeStamp;        /// BYTE->unsigned char
        public byte TimeFlag;        /// BYTE->unsigned char
        public byte SendType;        /// BYTE->unsigned char
        public byte RemoteFlag;        /// BYTE->unsigned char
        public byte ExternFlag;        /// BYTE->unsigned char
        public byte DataLen;        /// BYTE[8]
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I1)]
        public byte[] Data;        /// BYTE[3]
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I1)]
        public byte[] Reserved;
    }
函数声明这样:
       [System.Runtime.InteropServices.DllImportAttribute("ControlCAN.dll", EntryPoint = "VCI_Receive", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static extern uint VCI_Receive(uint DevType, uint DevIndex, uint CANIndex, ref VCI_CAN_OBJ pReceive, uint Len, int WaitTime);
然后在文件里这样使用: const uint recv_size = 100;
            VCI_CAN_OBJ[] sReceive = new VCI_CAN_OBJ[recv_size];            for (int i = 0; i < recv_size; i++ )
            {
                Byte[] data = new Byte[8];
                sReceive[i].Data = data;
            }
           uint packs = Can.VCI_Receive(NativeConstants.DEV_USBCAN2, can_index, 0, ref sReceive[0], recv_size , 1000);
                        if (packs > 0)
                        {
                           
                            for (int pack = 0; pack < packs; pack++)
                            {
                                recvive_length = sReceive[pack].DataLen;
                                receive_id = sReceive[pack].ID;
                                Array.Copy(sReceive[pack].Data, receive_data, sReceive[pack].DataLen);
                                can_receive(recvive_length);
                                Thread.Sleep(10);
                            }
                        }可是我只能得到第一帧的数据,很确定的是,发送了2帧数据出来,第二帧的成员全是0了还请大虾指导一下该怎么调用这个?

解决方案 »

  1.   

    用另一种方法试一下,结构地址换 IntPtr 类型,然后调用前分配空间:
    IntPtr buff = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * 100);
    //Can.VCI_Receive
    // 转换成结构
    VCI_CAN_OBJ obj = new VCI_CAN_OBJ();
    Marshal.PtrToStructure(new IntPtr(buff.ToInt32() + Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * pack), obj);
    // 释放分配的空间
    Marshal.FreeHGlobal(buff);
      

  2.   

    这个...是这样吗? VCI_CAN_OBJ sReceive = new VCI_CAN_OBJ();
                            Marshal.PtrToStructure(new IntPtr(buff.ToInt32() + Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * recv_size), sReceive);                        uint packs = Can.VCI_Receive(NativeConstants.DEV_USBCAN2, can_index, 0, ref sReceive, recv_size, 1000);数据怎么取出来呢?