Monday, August 25, 2008

Marshaling an array of Type to C#

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:              }

No comments: