How to call a function in a DLL with a function pointer parameter?

  • Thread starter Thread starter David Rose
  • Start date Start date
D

David Rose

I have a DLL (not .NET) that takes a function pointer argument and calls
that function with an integer argument. The DLL is being called from C#.



So far, it is partially working, but the integer argument is getting
corrupted (MessageBoxes in the dll and C# fire).

I do not understand why the int parameter is getting corrupted calling the
callback function (Testing() in C#). ( probably I just don't understand
what I'm doing :-) )



If anyone could give me some help I'd be eternally greatful...



David



Here's the setup:



The DLL:

extern "C"

{

__declspec(dllexport) int __stdcall ExecuteCallback(int (*
pFunction)(int), int val)

{

MessageBox(NULL, "Got here", "got here", MB_OK);
// this fires ok



// val == 10 here - no corruption until inside the
callback

return (*pFunction)(val);

}

}



In C#:

namespace CsDriver

{

public class TestDlls

{

public TestDlls()

{

}



[DllImport("CallbackDll.dll",
CallingConvention=CallingConvention.StdCall)]

public static extern Int32 ExecuteCallback(IntPtr
pFunction, Int32 val2);

}

}



C# calling function:

private void OnTestItClick(object sender,
System.EventArgs e)

{

// delegate declaration:

// public delegate int
CallbackDelegate(int val);

CallbackDelegate cd = new
CallbackDelegate(Testing);



// get the function pointer

IntPtr fPtr =
cd.Method.MethodHandle.GetFunctionPointer();



int val = TestDlls.ExecuteCallback(fPtr,
10); // return value corrupted

MessageBox.Show(val.ToString());

}



private static int Testing(int val)

{

// parameter val is corrupted here!!!!

// val == 2012581943, not 10 as it
should



MessageBox.Show("In Testing()"); //
MessageBox fires ok

return val;

}
 
David,
__declspec(dllexport) int __stdcall ExecuteCallback(int (*
pFunction)(int), int val)

If you can modify the C source, you should change

int (*pFunction)(int)

to

int (__stdcall *pFunction)(int)

[DllImport("CallbackDll.dll", CallingConvention=CallingConvention.StdCall)]
public static extern Int32 ExecuteCallback(IntPtr pFunction, Int32 val2);

Change the first parameter type to CallbackDelegate. The runtime takes
care of marshaling it to a function pointer.



Mattias
 
Hi, David:
I suggest you declare delegate instead of IntPtr for the
function pointer in your dllimport. I think it will handle some marshal
issues which easily cause problems if you handle them by yourself.


[DllImport("CallbackDll.dll", CallingConvention=CallingConvention.StdCall)]
public static extern Int32 ExecuteCallback(CallbackDelegate callback, Int32
val2);


Hope it helps!
Qiu
 
Back
Top