在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
摘要:本文简要综述了几种常见的函数调用方式。 关键字:__stdcall,__cdecl,__thisclass,_fastcall 我们经常可以看到这样的函数声明:
其中修饰符__cdecl和__stdcall决定了函数的调用方式,具体涉及到三个方面: 1)函数参数的压栈顺序, 2)由函数调用者还是被调用者将参数出栈, 3)决定函数的修饰符和命名方式。 常见的调用方式有 __cdcel__cdcel它是CDeclaration的缩写,为C语言默认的函数调用方式,这种调用方式下,所有参数从右到左 依次入栈,这些参数由调用者清除,称为手动清栈所有参数从右到左依次入栈,这些参数由调用者清除,称 为手动清栈。被调用函数不需要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的 参数都不会产生编译阶段的错误。调用约定仅在输出函数名前加上一个下划线前缀,格式_functionname。 __stdcall__stdcall是C++的标准调用方式(也是Pascal程序的缺省调用方式),所有参数从右到左依次入栈,如果 是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的 指令是 retnX,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。称为自动清栈。 __stdcall__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个”@”符号和其参数的字节数,格式 ,例如 :function(int a, int b),其修饰名为:。另外,函数在编译的 时候就必须确定参数个数,并且调用者必须严格的控制参数的生成。 __fastcall__fastcall是编译器指定的快速调用方式。由于大多数的函数参数个数很少,使用堆栈传递比较费时。 因此_fastcall通常规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过堆栈传递。不同编译器 编译的程序规定的寄存器不同。返回方式和_stdcall相同。调用约定在输出函数名前加上一个”@”符号,后 面也是一个”@”符号和其参数的字节数,格式为@functionname@number。 __thiscall__thiscall是为了解决类成员调用中this指针传递而规定的,仅仅应用于”C++”成员函数,另外,thiscall 不是关键词,因此不能被程序员指定。_thiscall要求把this指针放在特定寄存器中,该寄存器由编译器决 定。VC使用ecx,Borland的C++编译器使用eax。返回的方式和_stdcall相同。_fastcall和 _thiscall涉及的 寄存器由编译器决定,因此不能用作跨编译器的接口。所以Windows上的COM对象接口都定义为_stdcall调用方式。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13