使用PInvoke时,为什么要使用__stdcall?

时间:2013-04-05 11:15:07

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

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

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

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

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

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

  

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

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

3 个答案:

答案 0 :(得分:4)

x64上只有一个调用约定,因此指定哪个调用约定无关紧要。它总是在x64上被忽略。

在x86上,确保调用约定在接口的两端都匹配很重要。因此,如果您预计在x86上运行代码,那么现在就做到这一点是明智的。

答案 1 :(得分: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)并不关心调用约定,但希望上面的内容能够解决一些混乱。

答案 2 :(得分:2)

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

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

您可以在this answer

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