_cdecl 和 _stdcall

来源:互联网 发布:时光知味什么意思 编辑:程序博客网 时间:2024/05/09 01:14

关于这两个调用协议,从以下三个方面说一下我自己的理解:调用习惯,传参和弹栈方式,c编译器和c++编译器的命名规则。

1. 调用习惯:C/C++和MFC默认的函数调用方式为;_cdecl,而windows api 默认为_stdcall

2. 传参和弹栈方式:

        2.1调用_cdecl标示的函数时,该函数的 参数按照从右到左的方式入栈,而且要由调用函数者负责把参数弹栈并且完成栈的清理工作,所以一般使用                                                      _cdecl调  用规则的程序的exe文件比较大,因为他要有负责清理栈空间的代码。

       2.2调用_stdcall标示的函数时,参数也是从右到左的方式入栈,只是要由被调用的函数来完成栈的清理工作,由于函数本身知道传进来多少个参数,所                                                  以栈 的清理工作只需要一条 ret n就可以完成。所以当自己写的函数的参数个数不确定的时候,要用_cdecl规则。


3. c编译器和c++编译器的命名规则:c函数或者c++中的函数都是编译器通过对函数名字进行加工而成,只是C编译器和C++编译器的命名规则不同

    3.1当使用c编译器的时候:_stdcall:在函数名字前面加一个下划线,函数名和所有参数的字节数之间加上一个@,比如:void add(int a,intb),编译为:_add@8;

                                                  _cdecl:就在函数名字前面加一个下划线。

     3.2当使用c++编译器的时候:1 )  _stdcall:以“?”开始函数名后面加@@YG标示参数表开始,后跟参数,最后以@Z结束,当无参数时以Z结束。参数列表的第一项为函数的返回 值。参数表以代号标示:X--void,D--char ,E--unsigned char,F--short,H--int,I--unsigned int,J--long,K--unsigned long,M--float,N--double,_N--boo;PA标示指针,如果相同类型的指针重复出现以0代替,一个0标示重复一次。比如   void add(int a,int b)------?add@@YGXHH@Z; int add(int a,int b,int * p);------?add@@YGHHHPAH@Z;

                                                          2)_cdecl:其他都一样,只是把@@YG变为@@YI;



顺便说一下extern "c" ,它表明了该函数是用C语言编译器编译生成的函数,为了实现混合编程而用到的一个标示符。它的作用主要是防止函数编译时命名冲突或者无法在obj中找到相应的函数。

原创粉丝点击