C++编译时 函数调用约定 与 函数名修饰约定规则

 

 

函数调用约定(Calling convention)决定以下内容:
 1) 函数参数的压栈顺序
 2) 由调用者还是被调用者把参数弹出栈
 3) 产生函数名修饰的方法

__cdecl C/C++程序的默认调用规范
由 调用方 清空堆栈 产生的可执行文件较大
函数的参数个数可变.
可变参数函数需要 __cdecl 约定

__stdcall = WINAPI宏
由 被调方 清空堆栈 产生的可执行文件较小
函数的参数个数不可变.
为了让VB可以调用,需要用 __stdcall 调用规范来定义 C/C++ 函数.
请参看Microsoft KB153586文章:
 How To Call C Functions That Use the _cdecl Calling Convention.

__fastcall 使用ECX和EDX寄存器传送前两个双字(DWORD)或更小的参数
由 被调方 清空堆栈 产生的可执行文件较小
函数的参数个数不可变.

三者函数参数均采用从右到左的压栈方式

_beginthread 需要 __cdecl 的线程函数地址
_beginthreadex 和 CreateThread 需要 __stdcall 的线程函数地址
 当你 LoadLibrary 一个 DLL 文件后, 把GetProcAddress取得的函数地址传给
上面三个线程生成函数时,请务必确认实际定义在 DLL 文件的输出函数符合调用规范要求.
否则,编译成 Release 版后运行,可能会破坏堆栈,程序行为不可预测.

函数名修饰约定规则:
__stdcall 调用约定
  1).以"?"标识函数名的开始,后跟函数名;
  2).函数名后面以"@@YG"标识参数表的开始,后跟参数表;
  3).参数表以代号表示:
   X--void
   D--char
   E--unsigned char
   F--short
   H--int
   I--unsigned int
   J--long
   K--unsigned long
   M--float
   N--double
   _N--bool
   指针的表示: [PA+代号]
   后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复;

  4).参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;

  5).参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束.
  其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ".
  例如:
    int Test1(char *var1,unsigned long)-----"?Test1@@YGHPADK@Z"
    void Test2() -----"?Test2@@YGXXZ"

__cdecl 调用约定
 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YA".

__fastcall 调用约定
 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YI".

//另----------------------------------------------------------------------------------------------------------------------
__thiscall 调用约定
 类成员函数的默认调用约定,显式使用其的一个情况是类成员函数因为CLR而默认使用了__clrcall,
 为使其能够为本地(native)代码所调用而加上__thiscall标识符

__syscall 调用约定
操作系统内部使用的函数调用模型,由用户模式向核心模式跳转时使用的模型。由于用户模式和核心模式使用不同的栈,所以没办法使用栈来传递参数,所有参数通过寄存器传递,这限制了参数的数量。用户模式编程中不允许使用。

__fortran 调用约定
数学运算语言fortran使用的函数模型,由此得名。在C中调用由fortran编译的函数时使用。

__clrcall 调用约定
微软.Net框架使用的函数模型,托管(Managed)C++默认使用,也可以从非托管代码调用托管函数时使用。参数在托管栈上正序(从左至右)压栈,不使用普通栈。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值