我正在通过USB将64字节的数据包传输到微控制器。在微控制器的C代码中,这些数据包具有以下结构:
typedef union
{
unsigned char data[CMD_SIZE];
cmd_get_t get;
// plus more union options
} cmd_t;
使用
typedef struct
{
unsigned char cmd; //!< Command ID
unsigned char id; //!< Packet ID
unsigned char get_id; //!< Get identifier
unsigned char rfu[3]; //!< Reserved for future use
union
{
unsigned char data[58]; //!< Generic data
cmd_get_adc_t adc; //!< ADC data
// plus more union options
} data; //!< Response data
} cmd_get_t;
并且
typedef struct
{
int16_t supply;
int16_t current[4];
} cmd_get_adc_t;
在C#的PC端,我已经提供了一个返回64字节数据包作为Byte[]的函数。该函数使用Marshal.Copy将接收到的数据复制到Byte[]数组中。然后,我使用了一个格式为结构体的C#结构:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct COMMAND_GET_ADC
{
public byte CommandID;
public byte PacketID;
public byte GetID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
public byte[] RFU;
public short Supply;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public short[] Current;
}
我再次使用Marshal.Copy将字节数组复制到结构体中,以便可以按照结构化数据的方式进行操作,例如:
COMMAND_GET_ADC cmd = (COMMAND_GET_ADC)RawDeserialize(INBuffer, 1, typeof(COMMAND_GET_ADC));
short supply = cmd.Supply;
使用
public static object RawDeserialize(Byte[] rawData, int position, Type anyType)
{
int rawsize = Marshal.SizeOf(anyType);
if(rawsize > rawData.Length)
{
return null;
}
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(rawData, position, buffer, rawsize);
object retobj = Marshal.PtrToStructure(buffer, anyType);
Marshal.FreeHGlobal(buffer);
return retobj;
}
这种方法感觉就像是在复制数据,可能并不是最有效的实现方式。我还需要将结构化数据转换回字节数组以便向设备发送指令。我有一个使用相同过程的方法(即使用结构体,然后将其序列化为字节数组并将字节数组传递给写入函数)。
是否有更好的替代方案?