1

我正在与一些本机库进行互操作,该库具有一些非自然对齐功能,我想在 .NET 结构中模拟布局。检查这两个结构:

public struct Int3
{
    public int X;
    public int Y;
    public int Z;
}

public struct MyStruct
{
    public short A;
    public Int3 Xyz;
    public short B;
}

因此,在 .NET 中,它使用自己的布局规则来创建布局,即对齐方式为 min(sizeof(primitiveSize), StructLayout.Pack)。所以 MyStruct 的布局将是:

[oo--] MyStruct.A (2 bytes data and 2 bytes padding)
[oooo oooo oooo] MyStruct.Xyz (3 int, no padding)
[oo--] MyStruct.B (2 bytes data and 2 bytes padding)

我想做的是,我想将 Int3 的对齐方式更改为 8 个字节,例如:

[StructLayout(Alignment = 8)]
public struct Int3 { .... }

然后 MyStruct 的布局将变为:

[oo-- ----] MyStruct.A (2 bytes for data, and 6 bytes padding, to align next Xyz to 8
[oooo oooo oooo ----] MyStruct.Xyz (4 bytes padding for alignment of 8)
[oo-- ----] (6 bytes padding, because the largest alignment in this struct is 8)

所以,我的问题是:

1).NET中是否有这样的属性来控制这样的非自然对齐?

2)如果没有这样的内置属性,我知道还有其他属性如StructLayout.Explict、OffsetAttribute、StructLayout.Size、StructLayout.Pack。有了这些属性,我可以手动模拟这个布局,但是不好用。所以我的第二个问题是,有没有办法挂钩 .NET 结构布局创建,我可以干扰结构布局?我的意思是,我可以创建一个自定义属性来指定对齐方式,然后我计算布局,但我不知道如何干扰.NET 使用该布局。

问候,翔。

4

2 回答 2

2

除了 StructLayout.Explicit (这就是这样一种机制)之外,没有其他方法可以像您想要的那样“连接到 .NET”。互操作是一种非常特殊的需求,除了标准的 WinAPI 案例之外,您不应该期望它很容易。在您的情况下,除非您正在处理具有这种不寻常对齐方式的真正大量不同的结构,否则最好使用 MyStruct 上的 StructLayout.Explicit 将其拼写出来。

于 2013-04-07T10:41:16.740 回答
1

几乎任何结构都将存储为堆对象的一部分(作为类字段,或作为存储为类字段的结构的字段等)。.net 32​​ 平台将大对象堆上的对象对齐到16 字节边界,但其他对象以 4 字节边界。除非一个对象是在 LOH 上手动分配的,或者是一个超过 999 个双精度数的数组[由于真正残酷的 hack,恕我直言],否则没有任何有意义的方法可以确保比 4 字节对齐更具体的内容。即使在某个时刻,未固定的结构是 16 字节对齐的,任何任意 GC 周期都可能重新定位它并更改该对齐方式。

于 2013-04-08T17:05:09.847 回答