错误:指定的结构必须是可拼合的或具有布局信息 [英] Error: The specified structure must be blittable or have layout information

查看:49
本文介绍了错误:指定的结构必须是可拼合的或具有布局信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

是否有可能像这样写

array [1] .itemname = asd;

array[1].itemname=asd;

推荐答案

尝试将属性 [StructLayout(LayoutKind.Explicit)] 添加到您的结构测试中.

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

Marshal.SizeOf(array.Length)解析为Marshal.SizeOf(200)-200是一个int32,其报告大小为4.您需要执行 array.Length * Marshal.SizeOf(typeof(测试))

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))

问题在于,类型为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;
    }

数组必须从4字节边界开始,因此结构应如下所示:

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

可以通过将字符串编码为字节数组并按如下所示复制到struct中来完成字符串分配:

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

这篇关于错误:指定的结构必须是可拼合的或具有布局信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆