我有如下结构
[StructLayout(LayoutKind.Sequential)]
public struct MyStructType
{
[MarshalAs(UnmanagedType.U1)]
public byte stx;
public UInt16 cmdId;
public UInt16 status;
public UInt16 pktNo;
[MarshalAs(UnmanagedType.U1)]
public byte contPkt;
[MarshalAs(UnmanagedType.U1)]
public byte dataoffset;
public UInt16 dataLength;
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)]
public byte[] data;
public UInt16 checkSum;
[MarshalAs(UnmanagedType.U1)]
public byte cr;
}
我尝试使用以下代码将此结构转换为字节数组。
byte[] ConvertStructureToByteArray(MyStructType str)
{
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
但我得到了以下错误,因为他们不知道大小
Type 'MyStructType' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
问题是因为
public UInt16 dataLength;
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)]
public byte[] data;
dataLength 在运行时计算。如何将此结构转换为 ByteArray?
最佳答案
编码的限制
正如您已经注意到的,Marshal.SizeOf()
无法计算包含带有 UnmanagedType.LPArray
的byte
数组的结构的大小。但是,这并不意味着您不能自己计算。
但是,即使您这样做,您也会收到 Marshal.StructureToPtr
提示必须使用 SafeArray 或 ByValArray 的数据字段。
你应该检查this on MSDN为了了解如何将数组从托管传递到非托管。然而,对于结构中包含的数组,似乎:
The size can be set only as a constant
为什么不使用序列化?
Protocol Buffer 是一种将数据序列化为二进制的简单方法。此外,它还支持模型更改、模型共享和其他一些很酷的功能。
它有多种语言版本:
关于c# - 如何在 c#.net 中将结构转换为字节数组,但结构大小仅在运行时定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34308001/