私のソリューションには、関数をエクスポートするアンマネージド C++ DLL と、この関数を PInvoke するマネージド アプリケーションがあります。
ソリューションを .NET 3.5 から .NET 4.0 に変換したところ、この PInvokeStackImbalance "A call to PInvoke function [...] has unbalanced the stack"例外が発生しました。結局のところ、__stdcall だったので、__cdecl された関数を呼び出していました。
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 でどのように機能したのかに興味がありますか? (何度も繰り返される) 誰も (呼び出し先も呼び出し元も) スタックをクリーンアップせず、スタック オーバーフローやその他の不正行為を引き起こさず、正常に機能したのはなぜですか? Raymond Chen の記事で言及されているように、PInvoke には何らかのチェックがありますか? また興味深いのは、反対のタイプの規約違反 (__stdcall 呼び出し先を __cdecl のように PInvoked にする) がまったく機能せず、単に EntryPointNotFoundException が発生する理由です。