• 学习函数调用的约定方式


    之前没有注意到的一些关键字,比如WINAPI,CALLBACK,原来是这个__stdcall的意思,而如果不声明__stdcall的话,就按默认的__cdecl处理,而这两者是不能相互转化的。

    具体原因,看代码吧。

    代码:

     1 #include <windows.h>
     2 #include <stdlib.h>
     3 
     4 /**
     5 * @author:zanzan101
     6 */
     7 
     8 // 默认的情况,就是__cdecl类型的函数调用方式
     9 void func()
    10 {
    11     printf("func
    ");
    12     return;
    13 }
    14 
    15 void __cdecl func_cdecl()
    16 {
    17     printf("func_cdecl
    ");
    18     return;
    19 }
    20 void __stdcall func_stdcall()
    21 {
    22     printf("func_stdcall
    ");
    23     return;
    24 }
    25 void CALLBACK func_callback()
    26 {
    27     printf("func_callback
    ");
    28     return;
    29 }
    30 void WINAPI func_winapi()
    31 {
    32     printf("func_winapi
    ");
    33     return;
    34 }
    35 void PASCAL func_pascal()
    36 {
    37     printf("func_pascal
    ");
    38     return;
    39 }
    40 class A
    41 {
    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(要引入<windows.h>)
    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 }

    输出结果:

    func
    func_cdecl
    func_cdecl
    func_stdcall
    func_callback
    func_winapi
    func_pascal
    请按任意键继续. . .
  • 相关阅读:
    133
    132
    131
    130
    129
    128
    2019.10.16考试解题报告
    2019.10.15考试解题报告
    洛谷 P1352 没有上司的舞会
    2019.10.13考试解题报告
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3372912.html
Copyright © 2020-2023  润新知