4

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

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

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

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

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

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

让我的大脑感觉好像有风滚草吹过它。

4

3 回答 3

5

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

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

于 2013-04-05T11:20:04.217 回答
4

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

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

您将在此答案中找到有关调用约定和名称装饰的更多详细信息

于 2013-04-05T11:24:08.390 回答
3

您错过了 x64 和 Win32 完全不同的事实。Win32 是一个与 Windows 交互的 C API,它的调用约定__stdcall,而 x64 或 x86-64 是你的 CPU 寄存器的大小。(即 64 位宽)。

在 x86-64 调用约定下的 Wikipedia 文章中:

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

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

于 2013-04-05T11:20:42.003 回答