Search code examples
c#.netstructalignmentpinvoke

How to set non-natural alignment of a .NET struct?


I'm doing interop with some native library, which has some non-natural alignment feature which I want to simulate in .NET struct for the layout. Check these two structs:

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

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

So, within .NET, it uses its own layout rule to create the layout, which is, alignment would be min(sizeof(primitiveSize), StructLayout.Pack). So the layout of MyStruct would be:

[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)

What I want to do is, I want to change the alignment of Int3 to 8 bytes, like something:

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

Then the layout of MyStruct would became:

[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)

So, my question is:

1) Is there such an attribute in .NET to control the non-natural alignment like this?

2) If there is no such built-in attribute, I know there are other attributes such as StructLayout.Explict, OffsetAttribute, StructLayout.Size, StructLayout.Pack. With these attributes, I can simulate this layout manually, but it is not easy to use. So My second question would be, is there a way to hook into .NET struct layout creation which I can interfere the struct layout? What I mean is, I can create a custom attribute to specify the alignment, and then I calculate the layout, but I don't know how to interfere the .NET to use that layout.

Regards, Xiang.


Solution

  • There is no other way to 'hook into .NET' like you want that I am aware of than StructLayout.Explicit (which is just such a mechanism). Interop is quite a specialized need and, beyond the standard WinAPI cases, you should not expect it to be easy. In your case, unless you are dealing with truly large numbers of different structs with this unusual alignment, it's better to spell it out longhand with StructLayout.Explicit on MyStruct.