问题
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