Dereference a double IntPtr
A common PInvoke question is how to deal with a double pointer. More specifically, how can one dereference an IntPtr to another pointer without using unsafe code?
Dereferencing a double pointer is done the same way a dereference to any other structure is done: Marshal.PtrToStructure. PtrToStructure is used to transform a native pointer, in the form of an IntPtr, into a managed version of the native data structure the native pointer points to.
In the case of a double pointer, the native data structure the pointer points to is just another native pointer. The managed equivalent is the IntPtr (or UIntPtr) class.
For Example, say we had the following native data signature
void GetDoublePointer(int** ppData)
This function returns a pointer to a pointer that points to an int. (Pointer->Pointer->int). We can then use the following C# code to access the final int value.
[DllImport("PInvokeSample.dll")]
static extern void GetDoublePointer(IntPtr doublePtr);
static void Main(string[] args)
{
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
try
{
GetDoublePointer(ptr);
var deref1 = (IntPtr)Marshal.PtrToStructure(ptr, typeof(IntPtr));
var deref2 = (int)Marshal.PtrToStructure(deref1, typeof(int));
Console.WriteLine(deref2);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
Comments
Anonymous
November 05, 2008
PingBack from http://www.tmao.info/dereference-a-double-intptr-2/Anonymous
November 05, 2008
For similar cases I used 'ref' like: GetDoublePointer( ref IntPtr doublePtr ); Marshal.ReadInt32(...Anonymous
November 05, 2008
@Thomas Yes, using a ref eliminates the double pointer problem for this example. I chose to omit it here to make the example clearer. The majority of the time I get stuck with a double pointer is when it comes back as a member of a struct that was Marshalled.