【发布时间】:2018-01-18 05:47:52
【问题描述】:
__stdcall 和 __cdecl 调用约定规定函数名称前面必须有一个下划线:
C (__cdecl)
同样的限制适用于 32 位世界和 16 位世界。 参数从右向左推送(这样第一个 参数最接近栈顶),调用者清理 参数。 函数名称由前导下划线修饰。
__stdcall
这是用于 Win32 的调用约定,但以下情况除外 可变参数函数(必须使用 __cdecl)和极少数 使用 __fastcall 的函数。参数从右推到 离开 [上午 10:18 更正],被调用者清理堆栈。 功能 名称由前导下划线和尾随@符号装饰 后跟函数采用的参数的字节数。
我在 Visual C++ 中编译了以下代码(源文件的扩展名为.c,所以我猜源文件被编译为C 文件):
void __stdcall stdcallFunction(int i)
{
int j = 12345;
}
void __cdecl cdeclFunction(int i)
{
int j = 12345;
}
int main()
{
stdcallFunction(123);
cdeclFunction(123);
return 0;
}
我注意到编译后的目标文件中的函数名没有前导下划线:
__stdcall 和 __cdecl 调用约定的函数名称的前导下划线是可选的吗?
【问题讨论】:
-
根据 MS 文档,在 64 位环境中,函数不会被修饰。
-
它不是可选的,它是一个链接实现细节。声明和函数定义不匹配的故障恢复。否则,由于堆栈不平衡,这种不匹配会导致非常严重的运行时错误。
标签: c calling-convention