tags:

views:

340

answers:

3

Here is the code in C++ dll:

extern "C" _declspec(dllexport) int testDelegate(int (*addFunction)(int, int), int a, int b)
{
    int res = addFunction(a, b);
    return res;
}

and here is the code in C#:

public delegate int AddIntegersDelegate(int number1, int number2);

public static int AddIntegers(int a, int b)
{
  return a + b;
}

[DllImport("tester.dll", SetLastError = true)]
public static extern int testDelegate(AddIntegersDelegate callBackProc, int a, int b);

public static void Main(string[] args)
{
  int result = testDelegate(AddIntegers, 4, 5);
  Console.WriteLine("Code returned:" + result.ToString());
}

When I start this small app, I get the message from the header of this post. Can someone help, please?

Thanks in advance,

D

A: 

It is usually meaning an "interface mismatch" : the declaration used to compile the client is different from the actual version of dll.

Seb
+2  A: 

The function pointer argument of testDelegate needs to be marked with __stdcall, otherwise invoking it will corrupt the stack (because it uses different calling conventions.)

Adam Maras
+3  A: 

Adam is correct, you've got a mismatch on the calling convention on a 32-bit version of Windows. The function pointer defaults to __cdecl, the delegate declaration defaults to CallingConvention.StdCall. The mismatch causes the stack pointer to not be properly restored when the delegate call returns, triggering the diagnostic in the debug build of your C/C++ code.

To fix it on the C/C++ side:

typedef int (__stdcall * Callback)(int, int);

extern "C" _declspec(dllexport) int testDelegate(Callback addFunction, int a, int b)
{
    int res = addFunction(a, b);
    return res;
}

To fix it on the C# side:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate int AddIntegersDelegate(int number1, int number2);
Hans Passant
Ah, upvoting your answer for `CallingConvention.Cdecl` as I was entirely unaware of that.
Adam Maras
Guys, thank you so much. You've solved my problem.
Deveti Putnik
Though, this works for me when, instead[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int AddIntegersDelegate(int number1, int number2);I put:[UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int AddIntegersDelegate(int number1, int number2);
Deveti Putnik
StdCall is the default.
Hans Passant
Nevertheless, you saved the day. :)))
Deveti Putnik