C ++ dll的C#包装器; “运行时检查失败#0 – ESP的值未在函数调用中正确保存。”错误

这是C ++ DLL中的代码:

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

这是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()); } 

当我启动这个小应用程序时,我从这篇文章的标题中得到消息。 有人可以帮帮忙吗?

提前致谢,

d

Adam是正确的,你在32位版本的Windows上的调用约定上存在不匹配。 函数指针默认为__cdecl,委托声明默认为CallingConvention.StdCall。 当委托调用返回时,不匹配会导致堆栈指针无法正确恢复,从而在C / C ++代码的调试版本中触发诊断。

要在C / C ++端修复它:

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

要在C#端修复它:

  [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int AddIntegersDelegate(int number1, int number2); 

testDelegate的函数指针参数需要用__stdcall标记,否则调用它会破坏堆栈(因为它使用不同的调用约定。)

它通常意味着“接口不匹配”:用于编译客户端的声明与dll的实际版本不同。