Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing delegate to a unmanaged method which expects a delegate method with an int array pointer

I am working on a C# application which uses an unmanaged dll which as a method that takes in a function pointer as one of it's parameters. As I do not have access to the actual C++ source code for the unmanaged dll I can only rely on a snippet I have from a C++ sample which uses that the same dll. The problem I am having is that the delegate I have made to pass into the unmanaged method is not working.

Below is the DllImport of the method I am trying to use which takes the delegate I've created:

[DllImport("pos_tk.dll")]
static internal extern ErrorCode AddSIGHandle([MarshalAs(UnmanagedType.FunctionPtr)] SIG_Callback func);

Here is the delegate signature I currently have:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void SIG_Callback ([MarshalAs(UnmanagedType.LPArray)] ref int[] buf, int rev, object sender);

And this is the function the C++ sample snippet uses in which I based my delegate off of:

void __stdcall point_handle (int *buf, int rev, LPVOID pParam)

Now, before you tell me to change the ref int[] buf parameter of my delegate to ref int buf the program will throw an InvalidVariant error once the callback is attempted. The code snippet uses int *buf as an array of size rev.

Using the code I have above, the application throws an AccessViolationException when the callback is attempted. My hunch is that I should be using a different type for the ref int[] buf parameter, but I've tried everything I can think of. I've also been searching Google, SO, and MSDN all day but with no luck.

Anyone have any ideas?

As a final note, is this any way similar to how you can use a StringBuilder as a parameter for a unmanaged method that takes a char* parameter to retrieve a variable length string?

like image 306
LamdaComplex Avatar asked Sep 17 '25 00:09

LamdaComplex


1 Answers

Passing arrays back and forth is always a PITA...try this signature, it seems applicable:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void point_handle(
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
    int[] buf,
    int rev,
    IntPtr pParam);

EDIT: just to elaborate, when you've got a "C style" array (that is a T*) as well as the length both specified in the arguments, SizeParamIndex is your salvation; basically it says "Hey, there's an unknown-length array coming in, but the parameter at this index will tell you how many of them there are. Use both that and the type to help marshal"

like image 51
JerKimball Avatar answered Sep 19 '25 14:09

JerKimball