How do I convert a C# byte array into structured data?

Dun*_*nan 7 c# struct

I am passing 64 byte data packets over USB to a microcontroller. In the microcontroller C code the packets have the structure,

typedef union
{
    unsigned char data[CMD_SIZE];
    cmd_get_t get;
    // plus more union options
} cmd_t;
Run Code Online (Sandbox Code Playgroud)

with

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;
Run Code Online (Sandbox Code Playgroud)

and

typedef struct
{
    int16_t supply;
    int16_t current[4];
} cmd_get_adc_t;
Run Code Online (Sandbox Code Playgroud)

On the PC side in C# I have been provided with a function which returns the 64 byte packet as a Byte[]. The function uses Marshal.Copy to copy the received data into the Byte[] array. I then used a C# struct of the form

[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;
    }
Run Code Online (Sandbox Code Playgroud)

and again used Marshal.Copy to copy the byte array into the struct so that I could work with is as structured data, e.g.

COMMAND_GET_ADC cmd = (COMMAND_GET_ADC)RawDeserialize(INBuffer, 1, typeof(COMMAND_GET_ADC));
short supply = cmd.Supply;
Run Code Online (Sandbox Code Playgroud)

with

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;
}
Run Code Online (Sandbox Code Playgroud)

这只是感觉我正在制作大量的数据副本,并且它可能不是实现我想要的最有效的方式.我还需要将结构化数据转换回字节数组以获取设备的命令.我有一个使用相同过程的方法(即使用结构然后将其序列化为字节数组并将字节数组传递给写入函数).

还有更好的选择吗?

log*_*cnp 2

如果可以使用不安全代码,则可以使用“fixed”关键字将字节数组转换为指向结构的指针。