小弟在编写一个简单界面,使用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了还请大虾指导一下该怎么调用这个?
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了还请大虾指导一下该怎么调用这个?
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);
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);数据怎么取出来呢?