之前没有注意到的一些关键字,比如WINAPI,CALLBACK,原来是这个__stdcall的意思,而如果不声明__stdcall的话,就按默认的__cdecl处理,而这两者是不能相互转化的。
具体原因,看代码吧。
代码:
1 #include2 #include 3 4 /** 5 * @author:zanzan101 6 */ 7 8 // 默认的情况,就是__cdecl类型的函数调用方式 9 void func()10 {11 printf("func\n");12 return;13 }14 15 void __cdecl func_cdecl()16 {17 printf("func_cdecl\n");18 return;19 }20 void __stdcall func_stdcall()21 {22 printf("func_stdcall\n");23 return;24 }25 void CALLBACK func_callback()26 {27 printf("func_callback\n");28 return;29 }30 void WINAPI func_winapi()31 {32 printf("func_winapi\n");33 return;34 }35 void PASCAL func_pascal()36 {37 printf("func_pascal\n");38 return;39 }40 class A41 {42 public:43 void __cdecl do_something(){}44 void __stdcall do_something_else(){}45 void PASCAL do_something_else_else(){}46 };47 48 // 默认的情况,就是__cdecl类型的函数调用方式49 typedef void (*func_ptr)();50 51 // 也可以手动指明52 typedef void (__cdecl *func_ptr_cdecl)(); 53 typedef void (__stdcall *func_ptr_stdcall)();54 55 int main()56 {57 58 // __cdecl 标准C函数调用方式,参数从右往左入栈,父函数负责清空栈59 // __stdcall 标准C++函数调用方式,参数从右往左入栈,子函数负责清空栈,包括了CALLBACK和WINAPI(要引入 )60 // PASCAL PASCAL语言调用方式,参数从左往右入栈,子函数负责清空栈,但实际上。。。经查看发现,还是__stdcall???那__pascal呢???61 // __fastcall 可通过寄存器来传递参数62 // thiscall 是一种概念,而非程序员可以指定的关键字,用类的成员函数的一种调用方式63 64 65 // 正确方法:66 func_ptr p1 = func;67 p1();68 func_ptr_cdecl p2 = func_cdecl;69 p2();70 p1 = p2;71 p1();72 73 // 错误演示:74 // error C2440: “初始化”: 无法从“void (__stdcall *)(void)”转换为“func_ptr”75 // 两种调用方式不可转换76 // func_ptr q = func_stdcall;77 // q();78 79 // 正确方法:80 func_ptr_stdcall q = func_stdcall;81 q();82 q = func_callback;83 q();84 q = func_winapi;85 q();86 q = func_pascal;87 q();88 system("pause");89 return 0;90 }
输出结果:
funcfunc_cdeclfunc_cdeclfunc_stdcallfunc_callbackfunc_winapifunc_pascal请按任意键继续. . .