9

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ですか?すべての構造メンバー、IMOは整列しているようです。

4

1 に答える 1

9

このLayoutKind.Sequential構造の管理されていない表現にのみ影響します。これは、構造に非ブリット可能なタイプ(つまり、文字列)が含まれているためです。blittableタイプ
のみが存在する場合、管理された表現と管理されていない表現の両方を制御します(参照)。LayoutKind.Sequential

msあなたの場合、コンパイラはマネージド表現の2つの文字列の前に整数を置くことを決定します(デバッグ中にカーソルを合わせて展開するとわかりますSTRUCT2)。

とを使用することでこれを修正できます。これは、ブリット可能タイプと非ブリット可能タイプの両方のマネージド表現とアンマネージド表現の両方に影響するLayoutKind.ExplicitためSTRUCT1ですSTRUCT2Explicit

于 2012-12-24T18:58:49.147 に答える