c#-4.0 - PinvokeStackImbalance 使用 CallingConvention.Cdecl 调用 comctl32

标签 c#-4.0 pinvoke comctl32

我们刚刚将项目从 .NET 3.5SP1 升级到 .NET 4.5,现在我们通过从 comctl32 调用 DllGetVersion 来获取 PInvokeStackImbalance MDA。我已经阅读并了解该框架默认情况下不再能够适应不正确的调用约定。奇怪的是,我们已经指定了 CallingConvention.Cdecl,我认为这是正确的。如果我完全删除 CallingConvention 属性并使其默认 (CallingConvention.WinAPI),我们将不会获得 PInvokeStackImbalance。任何人都可以阐明这一点吗?操作系统是 Win 7 64 位,如果有什么区别的话,它是一个 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 is defined as :

#define CALLBACK __stdcall

附注:

CALLBACK, WINAPI, and APIENTRY are all used to define functions with the __stdcall calling convention. Most functions in the Windows API are declared using WINAPI. You may wish to use CALLBACK for the callback functions that you implement to help identify the function as a callback function.

就您而言,这意味着需要切换到 StdCall

关于c#-4.0 - PinvokeStackImbalance 使用 CallingConvention.Cdecl 调用 comctl32,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15253010/

相关文章:

winapi - 如何子类化 win32 控件并保持与旧版本 comctl32.dll 的兼容性?

当 list 添加为资源时,Delphi 5 导致 EAccessViolation

vba - 在 64 位 VBA 中使用 TaskDialogIndirect

c# - 在c#中从mysql数据库检索单词分数

c# - ViewModel 和 Command 之间的通信

c# - 需要将oracle函数转换成c#代码

c# - 在 C# 上导入的 DLL 中出现 "Unsigned Char * "错误

wpf - Windows 文件名中不允许使用哪些字符以及如何限制它们在 C# 中键入

c# - 使用 P/Invoke 编码双参数

c# - C++ LPSTR 到 C# 字符串 .Net Wrapper