我一直在使用PInvoke让我的C#应用程序调用我编写的C ++函数。
现在,我一直听到无处不在,我需要使用__stdcall
约定来定义那些外部可访问的函数。我的问题是:为什么?
到目前为止,我不小心忽略了这个建议,一切都像魅力一样。当我将__stdcall
添加到我的函数中时,一切都以相同的方式继续工作(或者至少看起来如此)。
This article表示__stdcall
用于Win32位功能,但我正在编译x64平台。这是否意味着我不应该使用__stdcall
或者是否意味着我错过了其他的东西?
请在回答时使用简单的英语。 ;-)这样的行(引自我链接的文章):
被调用者清理堆栈,因此编译器生成vararg函数__cdecl。
让我的大脑感觉到有风滚草吹过它。
答案 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
中找到有关调用约定和名称修饰的更多详细信息