Draško
Draško

Reputation: 2221

C# wrapper of c++ dll; "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call." error

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

Upvotes: 3

Views: 2596

Answers (3)

Hans Passant
Hans Passant

Reputation: 942040

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);

Upvotes: 11

Adam Maras
Adam Maras

Reputation: 26863

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.)

Upvotes: 3

Seb
Seb

Reputation: 2715

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

Upvotes: 0

Related Questions