函数调用约定总结

1. 函数调用约定,主要约束两件事
  • 参数传递顺序
  • 调用堆栈由谁(调用函数或被调用函数)清理

2. 常用函数调用约定: stdcall, cdecl, fastcall, thiscall, naked call

3. __stdcall表示:
  • 参数从右向左压入堆栈;
  • 函数被调用者清理堆栈;
  • C编译器函数名的修饰规则为:__functionname@number;(functionname为函数名,number为参数字节数)
  • C++编译器函数名的修饰规则为:?functionname@@YG******@Z;(“******”为函数返回值类型和参数类型表)
  • 使用场合:Windows API默认函数调用协议;

4. __cdecl表示
  • 参数从右向左压入堆栈;
  • 函数调用者清理堆栈;
  • C编译器函数名的修饰规则为:__functionname;(functionname为函数名,number为参数字节数)
  • C++编译器函数名的修饰规则为:?functionname@@YA******@Z;(“******”为函数返回值类型和参数类型表)
  • 使用场合:C/C++默认函数调用协议;
PS:
  • 函数实现和定义若使用不同的函数调用协议,则无法实现函数调用。
  • C语言和C++语言间若不进行特殊处理,也无法实现函数的互相调用。

实践举例:VS下查看调用约定
例子:

(1)__stdcall:WIN API约定,参数由右向左传递,由被调者清理堆栈;
编译后函数名为:_func@参数字节数(C编译);

(2)__cdcel:C/C++约定,参数由右向左传递,由调用者清理堆栈;
c编译后的函数名为:_func,
c++编译后的函数名为:_func@参数修饰串
这里的清理堆栈,是指对参数的清理,可通过反汇编查看。调用函数内部的参数由内部自己处理。

2. 函数名修饰
作用:用于修饰函数在编译后的函数名符号
extern "C":C风格函数名,在编译后函数名不变
C编译:

C++编译:

总结:不同的函数名修饰,导致函数符号不一致,从而使得函数重载的实现成为可能。在extern "C"的修饰方式下,是不允许函数重载的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值