3

我一直在使用PInvoke让我的C#应用​​程序调用我编写的C++函数。使用PInvoke时,为什么使用__stdcall?

现在,我一直听到无处不在,我需要用__stdcall惯例定义那些外部可访问的函数。我的问题是:为什么?

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

This article__stdcall用于Win32位功能,但我正在编译对付x64平台。这是否意味着我不应该使用__stdcall,还是意味着我错过了其他的东西?

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

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

让我的大脑感受到吹过它的风滚草。

回答

4

在x64上只有一个调用约定,因此不管您指定哪种调用约定。它在x64上始终被忽略。

在x86上,确保调用约定在接口的两侧相匹配是非常重要的。所以,如果你曾经预计在x86上运行你的代码,现在就明白这一点。

+0

这是有道理的更多细节。实际上,我应该让我的图书馆能够让任何人最终使用它,所以我会确保在需要的地方使用__stdcall。 – 2013-04-05 11:23:33

2

你错过了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)不在乎调用约定,但希望上面的问题清除了一些混淆。

+0

谢谢,这听起来很有用。 – 2013-04-05 11:22:15

+0

这不会清除任何东西。这里的术语是错误的。 Win32是一个具有32和64版本的API。而x64是最初由AMD指定的处理器架构。 – 2013-04-05 11:24:09

2

调用约定是32位代码中的历史事件。在64位代码中只有一个约定,所以你声明的无关紧要。

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

,可以找到关于调用约定和名字装饰this answer

相关问题