转载自:http://www.cnblogs.com/lidabo/archive/2012/11/21/2781484.html

stdcall, cdecl, pascal 区别

这三个参数都是告诉编译器参数的传递约定,参数的传递约定是指参数的传递顺序(从左到右还是从右到左)和由谁来恢复堆栈指针(调用者或者是被调用者),在 Win16下有两种约定: C 和 PASCAL。

C约定规定参数传递顺序是从右到左,即最右边的参数最先压栈,由调用者恢复堆栈指针。

PASCAL约定和C约定正好相反,它规定参数是从左向右传递,由被调用者恢复堆栈。

STDCALL是C约定和PASCAL约定的混合体,它规定参数的传递是从右到左, 恢复堆栈的工作交由被调用者完成。Win32只用STDCALL约定, 但除了一个特例, 即: wsprintf。

__stdcall 这是一种函数调用方式。 __stdcall方式函数的参数压栈顺序从右到左,是Pascal 缺省调用方式,通常用于win32 API中,自己在退出时清空栈。

__stdcall将参数压栈是按C语言的顺序(从右到左),但与C语言不同的是它是由被调用者将参数从栈中清除,所以它的编译文件比_cdecl小。

__stdcall是Windows  API函数中默认的调用约定,VB、VFP等也采用这个约定。

__cdecl是C语言采用的默认调用方法,对于传送参数的内存栈却是由调用者来维护的。实现可变参数的调用只能用该方法。是MFC的缺省调用参数。

__fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数。

调用约定           压参数入栈顺序     把参数弹出栈者         函数修饰名(Calling convention)
-------------------------------------------------------------------------
__cdecl              右->左                     调用者                          _function   
__fastcall           右->左                     被调用者                       @function@nnn    
__stdcall            右->左                     被调用者                      _function@nnn
__pascal           左->右                      被调用者                      _function@nnn
-------------------------------------------------------------------------

以上几个关键词可在“windef.h”头文件中找到:

#define CALLBACK    __stdcall

#define WINAPI      __stdcall

#define WINAPIV     __cdecl

#define APIENTRY    WINAPI

#define APIPRIVATE  __stdcall

#define PASCAL      __stdcall

#define cdecl _cdecl

#ifndef CDECL#define CDECL _cdecl

#endif

几乎我们写的每一个WINDOWS API函数都是__stdcall类型的,为什么??

首先,我们谈一下两者之间的区别:WINDOWS的函数调用时需要用到栈(STACK,一种先入后出的存储结构)。当函数调用完成后,栈需要清除,这里就是问题的关键,如何清除??如果我们的函数使用了__cdecl,那么栈的清除工作是由调用者,用COM的术语来讲就是客户来完成的。这样带来了一个棘手的问题,不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。如果使用__stdcall,上面的问题就解决了,函数自己解决清除工作。所以,在跨(开发)平台的调用中,我们都使用__stdcall(虽然有时是以WINAPI的样子出现)。那么为什么还需要_cdecl呢?当我们遇到这样的函数如fprintf()它的参数是可变的,不定长的,被调用者事先无法知道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用_cdecl。

stdcall, cdecl, pascal 区别(转载)的更多相关文章

  1. C++函数调用方式约定stdcall,cdecl,pascal,naked,thiscall,fastcall

    https://www.cnblogs.com/xiangtingshen/p/11014514.html C++函数调用约定_cdecl约定:参数:从右向左依次入栈堆栈平衡:调用方平衡 #inclu ...

  2. Atitit 函数调用的原理与本质attilax总结 stdcall cdecl区别

    Atitit 函数调用的原理与本质attilax总结 stdcall cdecl区别 通常来说函数调用要用到的两条基本的指令:”CALL”指令和”RET”指令.”CALL”指令将当前的指令指针(这个指 ...

  3. apache与nginx日志文件的区别(转载)

    apache与nginx日志文件的区别 转载:http://www.xfcodes.com/apache/log/3270.htm 导读:apache与nginx日志文件的区别,在apache与ngi ...

  4. FB01与F-02的区别(转载)

    FB01与F-02的区别(转载) FB01 : a) ''Post Document'' b) No doc type as SA automatically comes. c) No automat ...

  5. stdcall与cdecl的区别

    1 区别 VC++的C/C++函数有两种基本的调用约定:__stdcall.__cdecl.它们有什么区别呢?请参考下表:     __stdcall __cdecl 函数代码 C int __std ...

  6. IIS7 经典模式和集成模式的区别(转载)

    转载地址:http://www.poluoluo.com/server/201301/193110.html 升级过程中出现了比较多的问题,前面文章也提到过几个.这次就主要介绍下httpHandler ...

  7. Minitab中相关系数R-Sq和修正R-Sq(adj)的意思,计算公式和区别[转载]

    转载自:http://www.pinzhi.org/thread-7762-1-1.html Minitab中相关系数R-Sq和修正的相关系数R-Sq(adj)的意思,计算公式和区别 在Minitab ...

  8. java 字节流和字符流的区别 转载

    转载自:http://blog.csdn.net/cynhafa/article/details/6882061 java 字节流和字符流的区别 字节流与和字符流的使用非常相似,两者除了操作代码上的不 ...

  9. cursor 与refcursor及sys_refcursor的区别 (转载)

    楼主标明是转载的,我只把我转载的地址发上来 http://www.cnblogs.com/honliv/archive/2011/07/21/2112639.html 显式是相对与隐式cursor而言 ...

随机推荐

  1. PHP中"->"和"=>"的区别

    =>不是运算符,这个是数组特有的指针符号..是定义数组时做键.值映射用的.foreach($_POST AS $key=>$value){...}遍历数组的时候,就是将$_POST数组的键 ...

  2. Objective-C 中,atomic原子性一定是安全的吗?

    我们在学习OC的时候认为,atomic使用了原子性,保证了线程安全,事实真的是这样吗? nonatomic的内存管理语义是非原子性的,非原子性的操作本来就是线程不安全的,而atomic的操作是原子性的 ...

  3. 多表关联 update

    UPDATE t_invests INNER JOIN t_user_coupons ON t_invests.user_coupon_id = t_user_coupons.id SET t_inv ...

  4. Twitter API 申请key

    最近听了一下coursera的python课(https://www.coursera.org/learn/python-network-data/home/welcome),讲的挺简单也挺有意思.其 ...

  5. MyEclipse使用前优化与配置

    全局优化 1 设置默认编码方式 首选项>  General > Workspace >  GBK改成UTF-8 2 设置默认文件默认打开方式 首选项>  General > ...

  6. 浏览器 HTTP 协议缓存机制详解

    最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...

  7. 深入理解javascript--笔记

    书写可维护的代码 1,最小全局变量   在js中不用声明变量就可以直接使用,因此注意不要没有声明就使用.(无意中创建的全局变量)比如使用任务链进行var声明.var a=b=12;正确写法为var   ...

  8. JMS与MQ详解(有项目)

    <一>m2mGW项目 1.ActiveMQ概述     企业消息软件从80年代起就存在,它不只是一种应用间消息传递风格,也是一种集成风格.因此,消息传递可以满足应用间的通知和互相操作.但是 ...

  9. 用JS实现的类似QQ密码的输入特效

    <input ID="_PSD"></input> <script> function passwordText(ID,pd,mark){ ma ...

  10. [ JS 进阶 ] 基本类型 引用类型 简单赋值 对象引用

    ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型.也有其他的叫法,比如原始类型和对象类型,拥有方法的类型和不能拥有方法的类型,还可以分为可变类型和不可变类型,其实这些叫法都是依据这两 ...