#define CALLBACK __stdcall
#define WINAPI __stdcall
#define WINAPIV __cdecl
#define APIENTRY WINAPI
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
#define cdecl _cdecl
#define CDECL _cdecl
__cdecl,__stdcall是声明的函数调用协议.主要是传参和弹栈方面的不同.一般c++用的是__cdecl,windows里大都用的是__stdcall(API)
__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。
__stdcall调用约定用于调用Win32 API函数。采用__stdcall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。
__fastcall约定用于对性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall
__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”。
VC++对函数的省缺声明是“__cedcl“,将只能被C/C++调用.
Reference
1. __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介
2. __stdcall,__cdecl,__fastcall的区别
3. GPGPU-Sim安装