Sunday, January 08, 2006

Marshaling an array of data

This falls under the category of methods I wish had been added to some of the BCL classes but weren't. When working with Win32 API calls you often end up with a pointer that contains an array of data you want to get access to. Here's a generic method for getting that array.


public static class MarshalHelper
{
internal static T[] PtrToArray<T>(IntPtr ptr, int count)
where T : struct
{
IntPtr current = ptr;
T[] array = new T[count];

for (int i = 0; i < count; i++)
{
array[i] = MarshalHelper.PtrToStructure<T>(current);
current = new IntPtr(current.ToInt32() + Marshal.SizeOf(typeof(T)));
}

return array;
}
}
}

On the other hand I can understand why they didn't add this method. The line that contains "current.ToInt32()" isn't entirely correct on 64 bit systems. It should be ToInt64 instead. But what impact will that have on a 32 bit system. Probably be minutely slower.


What is going to be really neat is when the next version of the c# compiler comes out with Method Extenders. Without any changes to the CLR we will have the ability to add methods to pre-existing classes. That way I can make my MarshalHelper class into a true extender of System.Runtime.InteropServices.Marshal. Then calling my method becomes "Marshal.PtrToArray(myPtr, 3)".

0 Comments:

Post a Comment

<< Home