如何设置.net结构体的非自然对齐

本文关键字:结构体 非自然 对齐 net 何设置 设置 | 更新日期: 2023-09-27 18:08:05

我正在与一些本地库进行互操作,这些库具有一些非自然对齐功能,我想在。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。显式,OffsetAttribute, StructLayout。大小,StructLayout.Pack。有了这些属性,我可以手动模拟这个布局,但它不容易使用。所以我的第二个问题是,有没有一种方法挂钩到。net结构布局创建,我可以干扰结构布局?我的意思是,我可以创建一个自定义属性来指定对齐方式,然后我计算布局,但我不知道如何干扰。net使用该布局。

问候,湘.

如何设置.net结构体的非自然对齐

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

几乎任何结构都将作为堆对象的一部分存储(无论是作为类字段,还是作为存储为类字段的结构的字段,等等)。net 32平台将大对象堆上的对象对齐为16字节边界,但其他对象对齐为4字节边界。除非对象是在LOH上手动分配的,或者是一个超过999个双精度的数组(这是由于一个真正可怕的黑客),否则没有任何有意义的方法来确保比4字节对齐更具体的东西。即使在某个时刻,未固定结构是16字节对齐的,任何任意GC循环都可能重新定位它并改变这种对齐方式。