C# 中的联合:结构成员似乎没有对齐 [英] Unions in C#: Structure Members Do Not Seem to be Aligned

查看:30
本文介绍了C# 中的联合:结构成员似乎没有对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了以下结构来模拟 C++ 联合(最终将用于 C++ 互操作):

I have defined to following structures to emulate a C++ union (which will eventually be used for C++ Interop):

[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 的相等性:

I have written the following test code which assigns a value to Struct1.guid and tests for equality to 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,似乎都是一致的.

Why does Struct2.guid not equal Struct1.guid and instead a segment of Struct2.guid's value seems to shift into Struct2.integer? All structure members, IMO, seem to be aligned.

推荐答案

LayoutKind.Sequential 仅影响此结构的非托管表示.这是因为该结构包含不可 blittable 类型(即字符串).
如果仅存在 blittable 类型LayoutKind.Sequential 将控制托管和非托管表示(参考a>).

The LayoutKind.Sequential only affects the unmanaged representation of this structure. This is because the structure contains non-blittable types (namely, strings).
If only blittable types were present, LayoutKind.Sequential would control both managed and unmanaged representation (reference).

在您的情况下,编译器决定将整数放在托管表示中的两个字符串之前(您可以看到,如果您在调试和展开 STRUCT2 时将鼠标悬停在 ms>).

In your case, the compiler decides to put the integer before the two strings in the managed representation (you can see that if you hover over ms while debugging and unfold STRUCT2).

您可以通过在 STRUCT1STRUCT2 中使用 LayoutKind.Explicit 来解决这个问题,因为 Explicit 会同时影响两者blittable 和非 blittable 类型的托管和非托管表示.

You can fix that by using LayoutKind.Explicit in both STRUCT1 and STRUCT2, because Explicit affects both managed and unmanaged representations for both blittable and non-blittable types.

这篇关于C# 中的联合:结构成员似乎没有对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆