Today I needed to Marshal an array of structs from a dllimport'ed function. The solution I used involved taking the pointer to the unmanaged array, and looping through it for each item. I ended up with two versions; one for value types and one for reference types.
Source:
1: public static T[] PtrToStructureArray<T>(IntPtr arrayPtr, int length) where T : struct
2: {
3: T[] array = new T[length];
4: if (length > 0)
5: {
6: int elementSize = Marshal.SizeOf(typeof(T));
7: Int64 addr = arrayPtr.ToInt64();
8:
9: for (int i = 0; i < array.Length; i++)
10: {
11: Marshal.PtrToStructure((IntPtr)(addr + elementSize * i), array[i]);
12: }
13: }
14: return array;
15: }
16: public static T[] PtrToClassArray<T>(IntPtr arrayPtr, int length) where T: new()
17: {
18: T[] array = new T[length];
19: if (length > 0)
20: {
21: int elementSize = Marshal.SizeOf(typeof(T));
22: Int64 addr = arrayPtr.ToInt64();
23:
24: for (int i = 0; i < array.Length; i++)
25: {
26: array[i] = new T();
27: Marshal.PtrToStructure((IntPtr)(addr + elementSize * i), array[i]);
28: }
29: }
30: return array;
31: }