(1) _stdcall调用
  _stdcall是Pascal程序的缺省调用方式,参数采用从右到左的压栈方式,被调函数自身在返回前清空堆栈。
  WIN32 Api都采用_stdcall调用方式,这样的宏定义说明了问题:

  #define WINAPI _stdcall

  按C编译方式,_stdcall调用约定在输出函数名前面加下划线,后面加“@”符号和参数的字节数,形如。

(2) _cdecl调用
  _cdecl是C/C++的缺省调用方式,参数采用从右到左的压栈方式,传送参数的内存栈由调用者维护。_cedcl约定的函数只能被C/C++调用,每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。

  由于_cdecl调用方式的参数内存栈由调用者维护,所以变长参数的函数能(也只能)使用这种调用约定。关于C/C++中变长参数(…)的问题,笔者将另文详述。

  由于Visual C++默认采用_cdecl 调用方式,所以VC中中调用DLL时,用户应使用_stdcall调用约定。
  按C编译方式,_cdecl调用约定仅在输出函数名前面加下划线,形如_functionname。

  (3) _fastcall调用
  _fastcall调用较快,它通过CPU内部寄存器传递参数。

  按C编译方式,_fastcall调用约定在输出函数名前面加“@”符号,后面加“@”符号和参数的字节数,形如@functionname@number。

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

首先,我们谈一下两者之间的区别:     

 WINDOWS的函数调用时需要用到栈(STACK,一种先入后出的存储结构)。当函数

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

__stdcall 与 __cdecl的更多相关文章

  1. 关于__stdcall和__cdecl调用方式的理解

    __stdcall和__cdecl都是函数调用约定关键字,先给出这两者的区别,然后举实例分析: __stdcall:参数由右向左压入堆栈:堆栈由函数本身清理. __cdecl:参数也是由右向左压入堆栈 ...

  2. C/C++:函数调用规则__stdcall,__cdecl,__pascal,__fastcall

    __cdecl __cdecl 是 C Declaration  的缩写,表示 C 语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈.被调用函数不会要求调用者传递多 ...

  3. 反汇编分析__stdcall和__cdecl的异同

    C++代码如下:.h头文件 #pragma once#ifdef DLLTestAPI#else#define DLLTestAPI _declspec(dllimport)#endifint DLL ...

  4. __stdcall,__cdecl,__fastcall的区别

    __stdcall,__cdecl,__fastcall的区别 标签: dll编译器pascalclassimportinitialization 2009-12-09 15:07 10472人阅读  ...

  5. __cdecl、__stdcall、__fastcall、thiscall 进栈、出栈区别

    https://en.wikipedia.org/wiki/X86_calling_conventions https://msdn.microsoft.com/en-us/library/984x0 ...

  6. __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介

    1. 今天写线程函数时,发现msdn中对ThreadProc的定义有要求:DWORD WINAPI ThreadProc(LPVOID lpParameter); 不解为什么要用WINAPI宏定义,查 ...

  7. 深入体会__cdecl与__stdcall

    在学习C++的过程中时常碰到WINAPI或者CALLBACK这样的调用约定,每每觉得十分迷惑.究竟这些东西有什么用?不用他们又会不会有问题?经过在网上的一番搜寻以及自己动手后,整理成以下的学习笔记.1 ...

  8. C调用约定__cdecl、__stdcall、__fastcall、__pascal分析

    参考原文地址:https://www.cnblogs.com/yenyuloong/p/9626658.html C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们 ...

  9. __cdecl、__stdcall、__fastcall 与 __pascal 浅析

    call 指令与 retn 指令 首先我们得了解 CALL 和 RETN 指令的作用,才能更好地理解调用规则,这也是先决条件. 实际上,CALL 指令就是先将下一条指令的 EIP 压栈,然后 JMP ...

随机推荐

  1. [SRH.Docker] HBase Java 第一天学习记录

    主要对HBase Table 的 简单操作, 直接上代码吧!!! http://pan.baidu.com/s/1hqzTTze       ui92

  2. 转载:监控每个节点(jvm部分)

    操作系统和进程部分 操作系统和进程部分的含义是很清楚的,这里不会描述的很详细.他们列出了基本的资源统计,例如CPU和负载.操作系统部分描述了整个操作系统的情况,进程部分只是描述了Elasticsear ...

  3. php读取xml文件内容,并循环写入mysql数据库

    <?php $dbconn = mysql_connect("localhost","root","root"); $db = mys ...

  4. Android实现传感器应用及位置服务

    Android实现传感器应用及位置服务 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 代码实现 这里需用获取加速度传感器和地磁传感器,手机获取旋转的方 ...

  5. gvim 常用配置

    set nocompatible set nu! filetype on syntax on set autoindent set ai! "set bg=dark set autoinde ...

  6. 基于OpenMP的矩阵乘法实现及效率提升分析

    一.  矩阵乘法串行实现 例子选择两个1024*1024的矩阵相乘,根据矩阵乘法运算得到运算结果.其中,两个矩阵中的数为double类型,初值由随机数函数产生.代码如下: #include <i ...

  7. iOS基础问答面试

    <简书社区 — Timhbw>iOS基础问答面试题连载(一)-附答案:http://www.jianshu.com/p/1ebf7333808d <简书社区 — Timhbw> ...

  8. unity3d中的Viewport

    Camera属性中有个Viewport Rect,如下图: X.Y为(0, 0)代表左下角,(1, 1)代表右上角:W和H分别是Viewport的宽(Width)和高(Height),摄像机的Aspe ...

  9. 【Exception】 java.lang.NoSuchMethodError: android.app.AlertDialog$Builder.setOnDismissListener

    f(Build.VERSION.SDK_INT >10) builder =newAlertDialog.Builder(getActivity(), R.style.Theme.Sherloc ...

  10. Java 7 中 NIO.2 的使用——第四节 文件和目录

    Files类提供了很多方法用于检查在于你真正实际去操作一个文件或目录.这些方法强烈推荐,也非常有用,也能避免很多异常的发生.例如,一个很好的习惯就是在你试着移动一个文件从一个地方到另一个地方的时候,先 ...