如何将byte []转换为结构(包含byte []成员和length成员)

时间:2018-12-18 12:45:54

标签: c# struct marshalling

我有一个结构定义为:

[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi,Pack = 1)]
internal struct Message
{
    [MarshalAs(UnmanagedType.U1, SizeConst = 1)]
    public byte age;
    [MarshalAs(UnmanagedType.U2, SizeConst = 2)]
    public ushort length;
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1,SizeConst = 502)]
    public byte[] data;
}
通过udp接收到的

有效载荷,当接收到byte []时,需要将其转换为struct。 data的长度指定为502,但实际上它应该是表示数据长度的length成员值,如果删除SizeConst attr,代码将抛出{{1} } Marshal处的异常。

Marshal.SizeOf(typeof(T))

例外信息:

  

public static T ToStruct<T>(this byte[] buf) { var lth = Marshal.SizeOf(typeof(T)); if (lth > buf.Length) return default(T); var ptr = Marshal.AllocHGlobal(lth); Marshal.Copy(buf, 0, ptr, lth); var structure = Marshal.PtrToStructure(ptr, typeof(T)); Marshal.FreeHGlobal(ptr); return (T)structure; } :不能将类型'Itms.Agent.IotBox.TieTa.Entity.Message'封送为非托管结构;无法计算出有意义的尺寸或偏移量。

我知道这在c / c ++中非常简单,但是C#没有类似的方法。 有帮助吗?

1 个答案:

答案 0 :(得分:1)

  

当接收到byte []时,需要将其转换为struct。数据长度指定为502,但实际上应该是表示数据长度的长度成员值

对于简单的元帅操作来说太复杂了。您可能必须手动进行序列化/反序列化,例如:

byte[] payload = ...
var age = payload[0];
var len = (payload[1] << 8) | payload[2]; // invert depending on endianness
byte[] data = len == 0 ? Array.Empty<byte>() : new byte[len];
Buffer.BlockCopy(payload, 3, data, len);
var msg = new Message(age, len, data);

这将意味着您可以删除所有属性,因为您没有使用任何编组功能。 另外... length字段似乎有点多余,因为它只是复制数组的长度。