问题描述
我定义了以下结构来模拟 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
).
您可以通过在 STRUCT1
和 STRUCT2
中使用 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# 中的联合:结构成员似乎没有对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!