我有一个结构定义为:
[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#没有类似的方法。 有帮助吗?
答案 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
字段似乎有点多余,因为它只是复制数组的长度。