我定义了这个结构
public enum E1 : byte
{
A,
B,
C
}
public enum E2 : byte
{
D,
E,
F
}
[StructLayout(LayoutKind.Sequential, Pack=4)]
public struct SomeStruct
{
public Int32 _var1; //4 byte
public E1 _var2; //1 byte(because Pack is 4 this will take 4 byte)
public E2 _var3; //1 byte(because Pack is 4 this will take 4 byte)
public UInt64 _var4; //8 byte
}
现在,因为我使用Pack = 4添加StructLayout属性,我希望我定义的每个变量都将数据字段的对齐保持为4.
所以我希望
int val = Marshal.SizeOf( typeof( SomeStruct ) );
但我检查代码,我发现val是16
那怎么可能呢? 我的误会在哪里?
答案 0 :(得分:3)
SizeOf
以字节指定大小。
现在,如果我们进行数学运算,我们就会看到:
Int32
有32
位,因此4
字节。Int64
有64
位,因此8
字节。enum
都在一个字节上编码,因此1
字节。一起1+1+4+8
因此14
字节。
但是:大多数系统都不喜欢使用字节:它们使用字(16位)或 dwords <来获取和存储数据/ strong>(32位)。由于最小化数据结构会导致操作切断数据并对其进行重新处理,因此它会包含尾随零。
如果您在这样的系统上工作,编译器可能希望将数据打包在16
位(或更高)的块中。这些更容易:如果您想要访问数组中的元素,则不必将两个单词提取到内存中,因为结构在单词之间被分割。
演示如何打包数据的实验:
using System.Runtime.InteropServices;
namespace Foo {
public enum E1 : byte
{
A,
B,
C
}
public enum E2 : byte
{
D,
E,
F
}
[StructLayout(LayoutKind.Sequential,Pack=4)]
public struct SomeStruct
{
public int _var1; //4 byte
public byte _var2; //1 byte(because Pack is 4 this will take 4 byte)
public byte _var3; //1 byte(because Pack is 4 this will take 4 byte)
public ulong _var4; //8 byte
public SomeStruct (int var1, byte var2, byte var3, ulong var4) {
this._var1 = var1;
this._var2 = var2;
this._var3 = var3;
this._var4 = var4;
}
}
}
Foo.SomeStruct i = new Foo.SomeStruct(1302,5,17,1425);
Marshal.SizeOf( typeof( Foo.SomeStruct ) );
sizeof(Foo.SomeStruct);
int size = sizeof(Foo.SomeStruct);
byte[] result = new byte[size];
IntPtr buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(i, buffer, false);
Marshal.Copy(buffer, result, 0, size);
结果:
{ 22, 5, 0, 0, 5, 17, 0, 0, 145, 5, 0, 0, 0, 0, 0, 0 }
因此,结构编码为:
0 32 40 48 64 128
+----------------+----+----+--------+--------------------------------+
| _var1 | _v2| _v3| ------ | _var4 |
+----------------+----+----+--------+--------------------------------+
如果您使用int
/ uint
对变量进行编码,则会得到:
{ 22, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 5, 0, 0, 0, 0, 0, 0 }
或:
0 32 64 96 128 192
+--------+--------+--------+--------+----------------+
| _var1 | _var2 | _var3 | ------ | _var4 |
+--------+--------+--------+--------+----------------+