为什么在违反调用约定的情况下(在.NET 3.5中)没有PInvoke崩溃?
我的解决方案有一个非托管C ++ DLL,它导出一个函数,一个托管应用程序PInvokes这个函数。
我刚刚将解决方案从.NET 3.5转换为.NET 4.0并得到了这个PInvokeStackImbalance“对PInvoke函数的调用[...]已经使堆栈失衡”异常。事实证明,我正在调用__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);
所以,我已经修复了这个bug,但现在我对.NET 3.5中的工作原理感兴趣吗?当没有人(既不是被叫者也不是调用者)清理堆栈时,为什么(多次重复)情况没有引起堆栈溢出或其他一些不当行为,但只是工作正常? Pnvoke中是否有某种检查,就像Raymond Chen在他的文章中提到的那样?
这也很有趣,为什么相反类型的破坏约定(让__stdcall被调用者像被__cdecl一样被PInvoked)根本不起作用,导致只有EntryPointNotFoundException。
没有找到相关结果
已邀请:
4 个回复
雄鞋谋塘
蹄渭信妥扳
钾涎净介
扭湘阀柿蹄
时,默认值为实际
,而不是
。 WinApi实际上不是约定,但代表系统的默认约定。也许它可能在.Net 3.5 WinApi中代表_cdecl,而现在它代表__stdcall 我真的不认为是这种情况,因为我记得在使用P / Invoke时总是必须指定__stdcall(或者更确切地说,WINAPI)。我不确定为什么它在.Net 3.5中有效。 (也许DllImport当时很懒,只是“忽略了”召唤大会 - 这很奇怪)