views:

65

answers:

2

I'm attempting to write a wrapper so that my C# application can use a DLL written in C. Here is a method defintion that i'm trying to wrap:

void methodA(const uint32_t *data); //c header declaration

The issue I'm having is trying to figure out how to give a equivalent pointer from c#. In c# I want it to operate on a:

 UInt32 data[]  //my c# object i want to be able to pass in

but how do I give an equivalent pointer in my wrapper? I have tried

ref data //my attempt at giving an equivalent pointer to the DLL

but that doesnt seem to be working. Using debug statements in the DLL I can see that the values it gets that way are not what I'm attempting to pass in.

So my question boils down to have do I properly wrap a c fuction that is using a pointer to reference an array?

+3  A: 

An array is already a reference, so it will get marshalled as a pointer to it. This should work:

[DllImport("my.dll")]
static extern void methodA(UInt32[] data);

If you need to pass data back to managed code, you need to decorate the parameter with the Out attribute:

[DllImport("my.dll")]
static extern void methodA([In, Out] UInt32[] data);

Usage:

uint[] data = new uint[] { 1, 2, 3, 4, 5 };
methodA(data);
Console.WriteLine(data[0]);

Another solution is to declare the parameter to be of type IntPtr:

[DllImport("my.dll")]
static extern void methodA(IntPtr data);

To make this work, you need to pin the array in order to get the IntPtr for it, or allocate memory in unmanaged space and copy the array contents to it. I wouldn't recommend these options, though.


ref is required if you want to pass a single value of a value type by reference:

[DllImport("my.dll")]
static extern void methodB(ref UInt32 data);
dtb
+1  A: 

Declare methodA with IntPtr parameter in P/Invoke declaration. To convert UInt32 array to unmanaged array, use Marshal.Copy Method (Int32[], Int32, IntPtr, Int32).

Code sample from this article is OK for you, call methodA after this line:

Marshal.Copy(managedArray, 0, pnt, managedArray.Length);
// now call methodA with pmt parameter
Alex Farber