工会在C#:结构成员不似乎对齐(Unions in C#: Structure Members Do

2019-08-04 16:03发布

我已经定义为以下结构来模仿C ++联盟(这将最终被用于C ++互操作):

[StructLayout(LayoutKind.Sequential)]
internal struct STRUCT1
{
    public Guid guid;

    public String str1;
    public String str2;
}

[StructLayout(LayoutKind.Sequential)]
internal struct STRUCT2
{
    public Guid guid;

    public String str1;
    public String str2;

    public Int32 i1;
}

[StructLayout(LayoutKind.Explicit)]
internal struct MASTER_STRUCT_UNION
{
    [FieldOffset(0)]
    public STRUCT1 Struct1;

    [FieldOffset(0)]
    public STRUCT2 Struct2;
}

[StructLayout(LayoutKind.Sequential)]
internal struct MASTER_STRUCT
{
    public MASTER_STRUCT_UNION Union;
}

我写了下面的测试代码分配一个值Struct1.guid和平等的测试Struct2.guid

class Class1
{
    public static void Test()
    {
        MASTER_STRUCT ms = new MASTER_STRUCT();

        bool match;
        ms.Union.Struct1.guid = new Guid(0xffeeddcc, 0xbbaa, 0x9988, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0);

        Console.WriteLine("Struct1.guid:\t\t{0}\n", ms.Union.Struct1.guid.ToString());

        Console.WriteLine("Struct2.integer:\t{0:x}", ms.Union.Struct2.i1);
        Console.WriteLine("Struct2.guid:\t\t{0}", ms.Union.Struct2.guid.ToString());


        match = ms.Union.Struct1.guid == ms.Union.Struct2.guid ? true : false;
    }
}  

为什么Struct2.guid不等于Struct1.guid和代替部分Struct2.guid的价值似乎转移到Struct2.integer ? 所有结构成员,国际海事组织,似乎要对齐。

Answer 1:

LayoutKind.Sequential只影响该结构的非托管表示。 这是因为该结构包含非Blittable型(即字符串)。
如果只有Blittable型存在, LayoutKind.Sequential将控制托管和非托管表示( 参考 )。

在你的情况下,编译决定把整前的管理表示这两个字符串(你可以看到,如果你将鼠标悬停在ms ,同时调试和展开STRUCT2 )。

您可以修复,通过使用LayoutKind.Explicit两个STRUCT1STRUCT2 ,因为Explicit影响两个blittable和非Blittable型托管和非托管的表示。



文章来源: Unions in C#: Structure Members Do Not Seem to be Aligned
标签: c# struct unions