Skip to main content

Pass a double pointer to a native library via P/Invoke (C#)

The easiest way for me to decide what to blog about here is to share the solution to problems I couldn't find an answer for with a simple Google search. This is one of those cases. First, there is a great quick reference for using P/Invoke at Code Project. So if you're new to the subject read that first and consider this a supplement.

The particular case being examined here is for dealing with a pattern where a native assembly returns a pointer then later needs you to pass a double pointer to that object.

1. Dealing with void pointers:

A native signature like this: public void* init();

Translates to: public static IntPtr init();

2. Dealing with double pointers:

A native signature like this: public void myFunc(void** someObj);

Translates to: public static void myFunc(ref IntPtr someObj);

3. The C# code then looks something like:

IntPtr handle = init();
myFunc(ref handle);

Looks obvious once you see the answer, right?

-----------------------

But what if the situation is reversed and you have to deal with a double pointer return value?

A native signature like this: public void** init();

Translates to: public static IntPtr init();

The reason is because a double pointer is literally a pointer to a pointer. So it is of type IntPtr regardless of how many levels it is nested.

Let's now redefine myFunc to be: public void myFunc(void* someObj);

Which translates to: public static void myFunc(IntPtr someObj);

There's no simple trick for this case. But here's what you do:

IntPtr handle = init();
var derefHandle = (IntPtr)Marshal.PtrToStructure(handle, typeof(IntPtr));
myFunc(derefHandle);