Reputation: 891
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?
Upvotes: 4
Views: 2505
Reputation: 16904
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"
Upvotes: 4