我们刚刚将我们的项目从。net 3.5SP1升级到。net 4.5,现在我们从comcomtl32调用DllGetVersion得到pinvokestack失衡MDA。我读了一些资料,了解到框架在默认情况下不再能够适应错误的调用约定。奇怪的是,我们已经指定了CallingConvention。我认为Cdecl是正确的。如果我完全删除CallingConvention属性,并让它默认(CallingConvention. winapi),我们不会得到pinvokestack失衡。有人能解释一下吗?操作系统是64位的win7,它是一个32位的应用程序,如果这有什么区别的话。我试过查看DllGetVersion函数的头文件,但我不知道调用约定应该是什么。
[DllImport("Comctl32.dll", EntryPoint = "DllGetVersion", CallingConvention = CallingConvention.Cdecl)]
private static extern int NativeDllGetVersion(ref DLLVERSIONINFO pdvi);
一般来说,任何Windows API调用都应该使用CallingConvention.StdCall
。
在本例中,如果您查看DllGetVersion
的声明,您将看到它被定义为:
HRESULT CALLBACK DllGetVersion(DLLVERSIONINFO *pdvi);
CALLBACK
定义为:
#define CALLBACK __stdcall
附注:
CALLBACK, WINAPI和APIENTRY都用于定义具有__stdcall调用约定的函数。Windows API中的大多数函数都是使用WINAPI声明的。您可能希望对您实现的回调函数使用CALLBACK,以帮助将该函数标识为回调函数。
在您的情况下,这意味着需要切换到StdCall
。