代码之家  ›  专栏  ›  技术社区  ›  DraÅ¡ko

C++DLL的C.*包装器;“运行时检查失败0”- ESP的值在函数调用中没有正确保存。

  •  3
  • DraÅ¡ko  · 技术社区  · 15 年前

    下面是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

    3 回复  |  直到 15 年前
        1
  •  11
  •   Hans Passant    15 年前

    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);
    
        2
  •  3
  •   Adam Maras    15 年前

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

        3
  •  0
  •   Seb    15 年前

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