如何在c#.net中将结构转换为Byte数组,但仅在运行时定义结构大小

时间:2021-04-24 03:13:07

I have a structure like below

我有一个像下面这样的结构

[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;
}

i tried to convert this structure to byte array by using below code.

我试图通过使用下面的代码将此结构转换为字节数组。

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;
    }

but i got the below error while because size they dont know

但我得到了以下错误,因为他们不知道的大小

Type 'MyStructType' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

类型'MyStructType'不能作为非托管结构封送;无法计算有意义的大小或偏移量。

the problem because of

因为这个问题

public UInt16 dataLength; 
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)] 
public byte[] data;

dataLength calculated on runtime. How can i convert this structure to ByteArray?

dataLength根据运行时计算。如何将此结构转换为ByteArray?

1 个解决方案

#1


0  

Limits of Marshalling

As you already noticed, Marshal.SizeOf() cannot compute the size of a struct containing a byte array with UnmanagedType.LPArray. However, it doesn't mean you cannot compute it by yourself.

正如您已经注意到的那样,Marshal.SizeOf()无法计算包含具有UnmanagedType.LPArray的字节数组的结构的大小。但是,这并不意味着你不能自己计算它。

However, even if you do so, you'll get Marshal.StructureToPtr complaining about data field which must use SafeArray or ByValArray.

但是,即使你这样做,你也会得到Marshal.StructureToPtr抱怨必须使用SafeArray或ByValArray的数据字段。

You should check this on MSDN in order to understand how to pass arrays from Managed to Unmanaged. However it seems that for arrays contained in a struct:

您应该在MSDN上检查这一点,以了解如何将数组从Managed传递到Unaged。但是,似乎对于结构中包含的数组:

The size can be set only as a constant

大小只能设置为常量

Why not using Serialization ?

Protocol Buffer is a simple way to serialize data to binary. Furthermore, it support model change, model share, and several other cool features.

协议缓冲区是将数据序列化为二进制的简单方法。此外,它支持模型更改,模型共享和其他一些很酷的功能。

It is available in several languages:

它有多种语言版本:

#1


0  

Limits of Marshalling

As you already noticed, Marshal.SizeOf() cannot compute the size of a struct containing a byte array with UnmanagedType.LPArray. However, it doesn't mean you cannot compute it by yourself.

正如您已经注意到的那样,Marshal.SizeOf()无法计算包含具有UnmanagedType.LPArray的字节数组的结构的大小。但是,这并不意味着你不能自己计算它。

However, even if you do so, you'll get Marshal.StructureToPtr complaining about data field which must use SafeArray or ByValArray.

但是,即使你这样做,你也会得到Marshal.StructureToPtr抱怨必须使用SafeArray或ByValArray的数据字段。

You should check this on MSDN in order to understand how to pass arrays from Managed to Unmanaged. However it seems that for arrays contained in a struct:

您应该在MSDN上检查这一点,以了解如何将数组从Managed传递到Unaged。但是,似乎对于结构中包含的数组:

The size can be set only as a constant

大小只能设置为常量

Why not using Serialization ?

Protocol Buffer is a simple way to serialize data to binary. Furthermore, it support model change, model share, and several other cool features.

协议缓冲区是将数据序列化为二进制的简单方法。此外,它支持模型更改,模型共享和其他一些很酷的功能。

It is available in several languages:

它有多种语言版本: