Error: The specified structure must be blittable or have layout information

两盒软妹~` 提交于 2019-12-14 03:56:14

问题


public class TestSerializer
{
    public static byte[] StructureToByteArray(Test[] array)
    {
        int size = Marshal.SizeOf(array.Length);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(array, ptr, true);//error
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);
        return arr;
    }

When I write the above code I got this error. But my structure is like this :

public struct Test
{
   [FieldOffset(0)]
   //   public string name;

    public Byte  icode;

    [FieldOffset(1)]
    public Byte method;

    [FieldOffset(2)]
    public Byte wav;

    [FieldOffset(3)]
    public Byte wav2;

    [FieldOffset(4)]
    public Byte unit;

    [FieldOffset(5)]
    public Byte temp;
    [fieldOffset(6)]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public byte[] itemname;

    //public float factor;
}

Test[] array = new Test[200];

I want to convert this 'array' to byte array and I also have a doubt in the following line

int size = Marshal.SizeOf(array.Length);

is it possible like writing this

array[1].itemname=asd;


回答1:


Try adding attribute [StructLayout(LayoutKind.Explicit)] to your struct test.

Marshal.SizeOf(array.Length) resolves to Marshal.SizeOf(200) - and 200 is an int32, for which this reports size of 4. You need to do array.Length * Marshal.SizeOf(typeof(Test))

The problem is that array of type Test is not blittable according to the documentation (while the struct itself is, if you've marked it with [StructLayout(LayoutKind.Explicit)] or LayoutKind.Sequential) and you need to do it yourself in a loop.

public static byte[] StructureToByteArray(Test[] array)
    {
        int structSize = Marshal.SizeOf(typeof(Test));
        int size = array.Length * structSize;
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);
        for (int i = 0; i < array.Length; i++ )
            Marshal.StructureToPtr(array[i], ptr+i*structSize, true);//error
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);
        return arr;
    }

Arrays must start on 4-byte boundaries, so the struct should look like this:

[StructLayout(LayoutKind.Explicit)]
public struct Test
{
    [FieldOffset(0)]
    public byte icode;

    [FieldOffset(1)]
    public byte method;

    [FieldOffset(2)]
    public byte wav;

    [FieldOffset(3)]
    public byte wav2;

    [FieldOffset(4)]
    public byte unit;

    [FieldOffset(5)]
    public byte temp;

    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public byte[] itemname;
}

the string assigment can be done via encoding string into byte array and copying into the struct as follows:

 Test[] array = new Test[200];
 byte[] temp = Encoding.UTF8.GetBytes("asd");
 array[0].itemname = new byte[20];
 Array.Copy(temp, array[0].itemname, temp.Length);


来源:https://stackoverflow.com/questions/25439983/error-the-specified-structure-must-be-blittable-or-have-layout-information

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!