• 【QQ空间转移】C/C++函数的调用约定


    2007-6-25 13:43

    __cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容:

    (1)由调用者还是被调用者把参数弹出栈,
    (2)以及产生函数修饰名的方法,C和C++不一样
    PS:至于参数的入栈顺序,C语言是从右到左,pascal是从左到右,与调用约定没有关系。



    出栈参数清理

    1、__stdcall:被调用的函数在返回前清理传送参数的内存栈,
    VB一般使用的是stdcall调用约定;Windows的API中,一般使用的是stdcall约定
    建议在不同语言间的调用中(如DLL)最好采用stdcall调用约定,因为它在语言间兼容性支持最好;
    在Windef.h中有如下的定义:
    #define CALLBACK __stdcall
    #define WINAPI  __stdcall

    2、__cdecl是C和C++程序的缺省调用方式。由调用者清理传送参数的内存栈。如果函数被调用多次,那么产生的可执行文件大小就会比__stdcall方式产生的大。但是对于可变参数的函数(参数有默认值),就只能使用__cdecl的调用方式,因为被调用者不知道传入了多少的参数。 main(或WinMain)函数的调用约定必须是__cdecl,不允许更改;

    3、__fastcall调用约定:和__stdcall的区别就是用ECX和EDX传送前两个双字(DWORD)或更小的参数

    调用约定可以通过工程设置:Setting...C/C++ Code Generation项进行选择,缺省状态为__cdecl。


    名字修饰约定

    1、C编译时函数名修饰约定规则:
    __stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个"@"符号和其参数的字节数,
    格式为_functionname@number,
    例如 :function(int a, int b),其修饰名为:_function@8

    __cdecl调用约定仅在输出函数名前加上一个下划线前缀,
    格式为_functionname。

    __fastcall调用约定在输出函数名前加上一个"@"符号,后面也是一个"@"符号和其参数的字节数,
    格式为@functionname@number。

    2、C++编译时函数名修饰约定规则:

    1)、以"?"标识函数名的开始,后跟函数名;

    2)、函数名后面"@@YG"表示__stdcall方式;"@@YA"表示__cdecl方式";"@@YI"表示__fastcall方式;

    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"代表一次重复;
    参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;
    参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。

    整个格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ"
    例如
    int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”
    void Test2()-----“?Test2@@YGXXZ”//第1个X表示输出参数是void,第2个X表示输出参数是void

    ps:
    1、_beginthread需要__cdecl的线程函数地址,_beginthreadex和CreateThread需要__stdcall的线程函数地址。2、extern "C" _declspec(dllexport) int __cdecl Add(int a, int b);
       typedef int (__cdecl*FunPointer)(int a, int b);

  • 相关阅读:
    ASE19 团队项目 模型组 scrum report集合
    ASE19团队项目alpha阶段model组 scrum2 记录
    ASE19团队项目alpha阶段model组 scrum1 记录
    ASE第二次结对编程——Code Search
    jdk中集成的jre和单独安装的jre有什么区别?
    window, linux, mac 比较文件和文件夹的区别
    Java 调用python、ruby 等脚本引擎
    微软软件工程 第一周博客作业
    绩效考核(2018.5.28~2018.6.3)
    数据库需求文档
  • 原文地址:https://www.cnblogs.com/chest/p/12548537.html
Copyright © 2020-2023  润新知