Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DLL Import malloc Double Indirect Pointers

Tags:

c

c#

dll

dllimport

I have a C function that takes several arguments of double indirected pointers.

something like this

int myFunction (int ** foo, int** bar, int **baz){
    int size = figureOutSizeFunction();
    *foo = (int*) malloc (sizeof(int) * size);
    return SomeOtherValue;
}

Now in C# I am trying to pass it a ref to an IntPtr, however the IntPtr is always zero. And when I pass those values to the next DLL C function the DLL fails with a System Access Violation. I know that the code works in a C only environment (I have a "main" that tests the code) however, it is not working when called from C#

What variable type do I need in C# to pass to the C DLL? ref ref int?

like image 432
Toymakerii Avatar asked May 12 '11 15:05

Toymakerii


1 Answers

When dealing with double pointers (**) the best way is to just marshal them as IntPtr.

public static extern int myFunction(IntPtr foo, IntPtr bar, IntPtr baz);

The digging into the double pointer is then done in managed code.

IntPtr foo, bar baz;
...
myFunction(foo, bar, baz); 

IntPtr oneDeep = (IntPtr)Marshal.PtrToStructure(foo, typeof(IntPtr));
int value = (int)Marshal.PtrToStructure(oneDeep, typeof(int));

The above code is obviously a bit ... ugly. I prefer to wrap it in nice extension methods on IntPtr.

public static class Extensions {
  public static T Deref<T>(this IntPtr ptr) {
    return (T)Marshal.PtrToStructure(ptr, typeof(T));
  }
}

Then the above can be rewritten as the more readable

int value = ptr.Deref<IntPtr>().Deref<int>();
like image 106
JaredPar Avatar answered Sep 22 '22 08:09

JaredPar