找到sizeof类型的对象?

时间:2015-02-17 19:17:24

标签: c#

我定义了这个结构

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

那怎么可能呢? 我的误会在哪里?

1 个答案:

答案 0 :(得分:3)

SizeOf字节指定大小。

现在,如果我们进行数学运算,我们就会看到:

  • Int3232位,因此4字节。
  • Int6464位,因此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          |
+--------+--------+--------+--------+----------------+