Fixed Size Array of Structure type

uray picture uray · Nov 2, 2011 · Viewed 10k times · Source

how do I declare fixed-size array of a structure type in C# :

[StructLayout(LayoutKind.Sequential,Pack=1), Serializable]
public unsafe struct MyStruct{
    ...
}

public class MyClass {
    ...
    public fixed MyStruct myStruct[256];
}

this will result to CS1663 : fixed size buffers of struct type is not allowed, how do I workaround this ?, I prefer not to use C# or "Managed Collection data structure" type, as I need to frequently marshall this to native C++

Answer

Mikayla Hutchinson picture Mikayla Hutchinson · Nov 2, 2011

If your C# struct uses only primitive data types and has exactly the same layout as your native struct in C++, you can get around these restrictions with manual memory management and unsafe code. As a bonus, you will improve performance by avoiding marshalling.

Allocate the memory:

IntPtr arr = Marshal.AllocHGlobal (sizeof (MyStruct) * 256);

This is basically malloc, so the allocated memory is outside the awareness of the GC.

You can pass the IntPtr to native code as if it were a MyStruct[256] and only the IntPtr will be marshalled, not the memory it points to. Native and managed code can access the same memory directly.

To read/write the structs in the array with C#, use C# pointers:

static unsafe MyStruct GetMyStructAtIndex (IntPtr arr, int index)
{
    MyStruct *ptr = ((MyStruct *)arr) + index;
    return *ptr;
}

static unsafe void SetMyStructAtIndex (IntPtr arr, int index, MyStruct value)
{
    MyStruct *ptr = ((MyStruct *)arr) + index;
    *ptr = value;
}

Don't forget to

Marshal.FreeHGlobal (arr);

when you're done with the memory, to free it.