我的解决方案有一个非托管 C++ DLL,它导出一个函数,以及一个 PInvoke 这个函数的托管应用程序。
我刚刚将解决方案从 .NET 3.5 转换为 .NET 4.0 并得到了这个 PInvokeStackImbalance “A call to PInvoke function [...] has unbalanced the stack”异常。事实证明,我正在调用 __cdecl'ed 函数,因为它是 __stdcall:
C++ 部分(被调用者):
__declspec(dllexport) double TestFunction(int param1, int param2); // by default is __cdecl
C#部分(调用者):
[DllImport("TestLib.dll")] // by default is CallingConvention.StdCall
private static extern double TestFunction(int param1, int param2);
所以,我已经修复了这个错误,但现在我对它在 .NET 3.5 中是如何工作的感兴趣?为什么(多次重复)没有人(被调用者或调用者)清理堆栈,没有导致堆栈溢出或其他一些不当行为,而是正常工作的情况?PInvoke 中是否有某种检查,就像 Raymond Chen 在他的文章中提到的那样?这也很有趣,为什么相反类型的破坏约定(让 __stdcall 被调用者像 __cdecl 一样被 PInvoked)根本不起作用,只导致 EntryPointNotFoundException。