【问题标题】:When using PInvoke, why use __stdcall?使用 PInvoke 时,为什么要使用 __stdcall?
【发布时间】:2013-03-27 18:48:32
【问题描述】:

我一直在使用 PInvoke 让我的 C# 应用程序调用我编写的 C++ 函数。

现在,我不断听到我需要使用__stdcall 约定定义那些外部可访问的函数。我的问题是:为什么?

到目前为止,我不小心忽略了这个建议,一切都像一个魅力。当我将__stdcall 添加到我的函数中时,一切都以相同的方式工作(或者至少看起来如此)。

This article 表示__stdcall 用于 Win32 位功能,但我正在针对 x64 平台进行编译。这是否意味着我毕竟不应该使用__stdcall,还是意味着我错过了其他东西?

请在回复时使用简单的英语。 ;-) 像这样的行(引用自我链接的文章):

被调用者清理堆栈,因此编译器使可变参数函数__cdecl。

让我的大脑感觉像是被风滚草吹过。

【问题讨论】:

    标签: c++ pinvoke calling-convention function-declaration stdcall


    【解决方案1】:

    在 x64 上只有一种调用约定,因此您指定哪种调用约定并不重要。它在 x64 上总是被忽略。

    在 x86 上,确保接口两侧的调用约定匹配很重要。因此,如果您预计在 x86 上运行您的代码,那么现在就获得它是明智的。

    【讨论】:

    • 这是有道理的。事实上,我应该让任何最终可能想要使用它的人都可以访问我的库,所以我会确保在需要的地方使用 __stdcall。
    【解决方案2】:

    调用约定在 32 位代码中是一个历史性的意外。 64 位代码中只有一种约定,因此无论您声明什么都无关紧要。

    如果您编写的非托管 32 位 DLL 可能会被非 C 或 C++ 编写的代码使用,那么使用 __stdcall 声明导出的函数有助于减少事故。大多数语言运行时都支持互操作以允许操作系统调用,因此它们将 __stdcall 设为默认值。

    您将在 this answer 中找到有关调用约定和名称修饰的更多详细信息

    【讨论】:

      【解决方案3】:

      您忽略了 x64 和 Win32 是完全不同的东西这一事实。 Win32 是一个与 Windows 交互的 C API,它的calling convention__stdcall,而 x64 或 x86-64 是你的 CPU 寄存器的大小。 (即 64 位宽)。

      在 x86-64 调用约定下的维基百科文章中:

      在 Windows 上下文中为 x64 架构编译时(无论是使用 Microsoft 还是非 Microsoft 工具),只有一种调用约定 — 此处描述的一种,因此 stdcall、thiscall、cdecl、fastcall 等是现在都一样了。

      显然 x64 (AMD) 并不关心调用约定,但希望以上内容能消除一些混乱。

      【讨论】:

      • 谢谢,这听起来很有用。
      • 这不会清除任何东西。这里的术语是错误的。 Win32 是一个同时具有 32 和 64 版本的 API。而 x64 是 AMD 最初指定的处理器架构。
      猜你喜欢
      • 2015-01-02
      • 2022-11-02
      • 2010-09-22
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 2020-02-07
      • 2021-12-01
      • 1970-01-01
      相关资源
      最近更新 更多