C/C++函数调用约定
函数声明部分的extern “C”表示连接规范(Linkage Specification)采用C,而不是C++.如果不写的
话.默认采用C++,当然也可以写成extern “C++”。
1.__cdecl:
C和C++默认的函数调用约定,参数从右到左顺序压入堆栈,由函数负责清理堆栈,把参数弹出. 也正是因为用来传送参数的堆栈是由调用函数维护的,所以实现可变参数的函数只能使用这种函数调用约定。因为每一个调用它的函数都要包含清理堆栈的代码,所以编译后的可执行文件的大小要比调用__stdcall函数的大。使用这种函数调用约定时,修饰后的函数名只是在原函数名前加上了一个_(下划线),并且不改变函数的大小写。
2.__stdcall:
函数调用约定通常用于Win32 API函数,参数按从右到左的顺序压入堆栈,由被调用函数负责清理堆栈,把参数弹出栈.使用这种函数调用约定时,修饰后的函数名在原函数名前加上了一个_(下划线),并且在原函数名后加上“@数字”,当然也不改变函数的大小写,@ 后面的数字表示参数所占的字节数,这里有一点要注意的,不足32位(4字节)的参数将在参数传递时被扩充到32位。
3.__fastcall:
顾名思义,特点就是快,因为它是靠寄存器来传递参数的。传递参数时,最左边的两个小于等于32位(4字节)的参数将被分别存入ECX和EDX寄存器,其余参数仍然按从右到左的顺序压入堆栈,由被调用函数负责清理堆栈,把参数弹出栈.使用这种函数调用约定时,修饰后的函数名在原函数名前加上了一个 @,并且在原函数名后加上“@数字”,同样不改变函数的大小写,@ 后面的数字表示参数所占的字节数,其实和__stdcall差不多,只是把最前面的_(下划线)换成了@。
4.__thiscall:
并不是C++ 的关键字,所以我们不能在程序中显式地指出采用这种函数调用约定. 它是C++ 成员函数默认的函数调用约定,参数按从右到左的顺序压入堆栈,由被调用函数负责清理堆栈,把参数弹出栈。在秘密传递this指针时,成员函数不仅将this指针存入到了ECX寄存器中,而且也存入到了堆栈中,但却是最后压入到堆栈,位置和采用__fastcall调用约定的函数的最左边的两个小于等于32位(4字节)的参数的位置相同。