错误:指定的结构必须是可拼合的或具有布局信息 [英] Error: The specified structure must be blittable or have layout information
问题描述
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))
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屋!