agrafix
agrafix

Reputation: 775

use c++ unsigned int *array in c#

I have a c++ .dll exporting a function with the following signature:

extern int __stdcall foobar(long ptr, unsigned int *array, unsigned int arraySize);

From c++ Code, I can use it like so:

std::vector<unsigned int> FooBar(6);
int res = foobar(ptr, &FooBar[0], (unsigned int)FooBar.size());

I'd like to use the dll from C# and I've tried this:

[DllImport("mydll.dll")]
public static extern int foobar(long ptr, uint[] arr, uint arrSize);

Call:

uint[] arr = new uint[6];
int count = Obj.foobar(ptr, arr, (uint)arr.GetLength(0)*32)

This throws an "PInvokeStackImbalance" error. What would the correct PInvoke signature look like?

Upvotes: 0

Views: 1533

Answers (1)

Breealzibub
Breealzibub

Reputation: 8095

You're going to need to make use of the MarshalAs attribute, for your array parameter. This essentially describes to the marshalling system how to convert between the C# managed type and your raw C++ function parameter.

[DllImport("mydll.dll")]
public static extern int foobar(
    IntPtr ptr, //Need more details on this parameter
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] uint[] arr,
    uint arrSize);

Your "ptr" parameter is a bit confusing, since it's not mentioned in your question, but it's most likely just something you can treat as a regular old C++ pointer, in which case IntPtr is the appropriate type.

In the MarshalAs attribute, we are telling the marshalling system to convert your "uint array" into a raw, long-pointer-compatible C++ array. The SizeParamIndex tells it to use the "arrSize" parameter, when allocating the array's size during conversion.

Upvotes: 1

Related Questions