C++的函数名修饰,__stdcall,__cdecl,__fastcall

在C++中,为了允许操作符重载和函数重载,C++编译器往往按照某种规则改写每一个入口点的符号名,以便允许同一个名字(具有不同的参数类型或者是不同的作用域)有多个用法,而不会打破现有的基于C的链接器。这项技术通常被称为名称改编(Name Mangling)或者名称修饰(Name Decoration)。
__stdcall、__cdecl和__fastcall是C++中的三种函数调用约定,它们主要区别在于函数参数的传递方式和堆栈的清理方式。

__stdcall

在Windows系统的API开发中,__stdcall约定是默认的调用约定,并且是必须使用的。如果没有正确指定__stdcall约定,可能会导致无法正常调用API函数,导致程序运行异常或崩溃。

同时需要注意的是,__stdcall修饰符只能用于全局函数或静态成员函数,不能用于虚函数、内联函数或非静态成员函数等。

下面是一个使用__stdcall修饰符的示例:

int function (int a ,int b)			 //不加修饰就是C调用约定
int __stdcall function(int a,int b,...)//明确指出C调用约定
__stdcall int function(int a,int b,...)

__stdcall还有一个重要的特性,即指定了函数调用约定,用于指定函数在调用时如何从调用者传递参数以及将参数传递给被调用者和返回值。Windows API使用的是__stdcall约定,将参数从右至左推入堆栈中,由调用者恢复函数的堆栈。
__stdcall修饰符是一种用于兼容不同编译器和平台的函数修饰符,可以用于指定函数的参数传递和调用方式,并且应该合理使用函数定义和声明中。

__cdecl

如果需要显式指定一个函数使用__cdecl,调用约定可以使用__cdecl修饰符来声明该函数。例如:

int function (int a ,int b)			 //不加修饰就是C调用约定
int __cdecl function(int a,int b) //明确指出C调用约定
{
    return a+b;
}

此时编译器会将该函数编译为使用__cdecl调用约定的函数。需要注意的是,通常情况下不需要使用__cdecl修饰符,除非有特殊的需求。

__fastcall

__fastcall是C++中的一种函数调用约定,用于指定函数参数的传递方式和寄存器的使用方式。它可以使函数调用更加高效。

使用__fastcall需要遵循以下几个步骤:

在函数声明或定义中使用__fastcall关键字指定函数调用约定。
例如:

int __fastcall myFunction(int a, int b,int c, int d);

按照指定的约定方式传递函数参数。__fastcall约定规定前两个整型或指针类型参数使用寄存器传递,其余参数使用堆栈传递。
例如:

int a = 1, b = 2, c = 3, d = 4;
int result = myFunction(a, b, c, d);

在上面的例子中,a和b会使用寄存器传递,c和d会使用堆栈传递。
注意:__fastcall约定只适用于x86架构的CPU,对于其他架构的CPU可能需要使用其他的函数调用约定。
总之,__fastcall可以使函数调用更加高效,但需要注意使用约定方式传递函数参数。

三个函数调用约定的区别

__stdcall:常见的函数调用约定,参数从右往左依次入栈,由被调用函数负责清理堆栈。在使用__stdcall约定时,函数的参数和返回值都会被压入堆栈中,堆栈的使用较大。
__cdecl:默认的函数调用约定,参数从右往左依次入栈,由调用方负责清理堆栈。在使用__cdecl约定时,函数的参数和返回值都会被压入堆栈中,堆栈的使用较大。
__fastcall:快速调用的函数调用约定,规定函数的前两个整型或指针类型参数使用寄存器传递,其余参数使用堆栈传递。在使用__fastcall约定时,函数的参数和返回值都会被压入堆栈中,但是由于使用了寄存器传递参数,因此可以减少堆栈的使用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
__cdecl 和 __stdcall 都是 C/C++ 函数调用约定,用于指明函数参数的传递方式和堆栈的清理方式。它们的主要区别在于参数传递的顺序、堆栈的清理方式和函数调用的速度。 __cdecl 是默认的调用约定,参数从右往左依次压入堆栈,由调用方清理堆栈。这意味着参数的顺序是反向的,而且每次函数调用后都需要调用方清理堆栈。例如: ```c++ void __cdecl myFunction(int a, int b, int c) { // function body } int main() { myFunction(1, 2, 3); return 0; } ``` 在上面的例子中,参数 3 会先被压入堆栈,然后是参数 2 和 1,最后调用函数 myFunction。函数 myFunction 执行完毕后,调用方负责清理堆栈。 __stdcall 是一种常用的调用约定,参数从右往左依次压入堆栈,由被调用方清理堆栈。这意味着参数的顺序是反向的,但被调用方负责清理堆栈。例如: ```c++ void __stdcall myFunction(int a, int b, int c) { // function body } int main() { myFunction(1, 2, 3); return 0; } ``` 在上面的例子中,参数 3 会先被压入堆栈,然后是参数 2 和 1,最后调用函数 myFunction。函数 myFunction 执行完毕后,被调用方负责清理堆栈。 总的来说,__stdcall 比 __cdecl 调用约定速度更快,因为不需要调用方清理堆栈。但是,__stdcall 只适用于固定数量的参数,而且参数的类型必须是已知的,因为被调用方需要知道清理堆栈的大小。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值