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);

Recent comments
31 weeks 6 hours ago
31 weeks 7 hours ago
34 weeks 3 days ago
40 weeks 1 day ago
48 weeks 6 days ago