我正在与一些本机库互操作,它有一些非自然对齐功能,我想在.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使用该布局。
问候,翔。
答案 0 :(得分:2)
除了StructLayout.Explicit(这就是这样一种机制)之外,没有其他方法可以像你想要的那样“挂入.NET”。 Interop是一个非常专业的需求,除了标准的WinAPI案例之外,你不应该期望它很容易。在你的情况下,除非你使用这种不寻常的对齐方式处理真正大量的不同结构,否则最好在MyStruct上使用StructLayout.Explicit进行拼写。
答案 1 :(得分:1)
几乎所有结构都将存储为堆对象的一部分(作为类字段,或作为存储为类字段的结构字段等).net 32平台对齐大型对象对象堆叠为16字节边界,但其他对象为4字节边界。除非在LOH上手动分配一个对象,或者是一个超过999个双倍的数组[由于一个真正残暴的黑客,恕我直言],没有任何有意义的方法可以确保比4字节对齐更具体。即使在某个时刻,未固定的结构是16字节对齐的,任何任意GC循环都可能重新定位它并改变该对齐。