__stdcall、__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。如下图所示,可以在IDE环境中设定所有函数默认的调用协议,还可以在函数定义时单独设定本函数的调用协议。

  1. 调用协议常用场合
    1. __stdcall:Windows API默认的函数调用协议。
    2. __cdecl:C/C++默认的函数调用协议。
    3. __fastcall:适用于对性能要求较高的场合。
  2. 函数参数入栈方式
    1. __stdcall:函数参数由右向左入栈。
    2. __cdecl:函数参数由右向左入栈。
    3. __fastcall:从左开始不大于4字节的参数放入CPU的ECX和EDX寄存器,其余参数从右向左入栈。
    4. 问题一:__fastcall在寄存器中放入不大于4字节的参数,故性能较高,适用于需要高性能的场合。
  3. 栈内数据清除方式
    1. __stdcall:函数调用结束后由被调用函数清除栈内数据。
    2. __cdecl:函数调用结束后由函数调用者清除栈内数据。
    3. __fastcall:函数调用结束后由被调用函数清除栈内数据。
    4. 问题一:不同编译器设定的栈结构不尽相同,跨开发平台时由函数调用者清除栈内数据不可行。
    5. 问题二:某些函数的参数是可变的,如printf函数,这样的函数只能由函数调用者清除栈内数据。
    6. 问题三:由调用者清除栈内数据时,每次调用都包含清除栈内数据的代码,故可执行文件较大。
  4. C语言编译器函数名称修饰规则
    1. __stdcall:编译后,函数名被修饰为“_functionname@number”。
    2. __cdecl:编译后,函数名被修饰为“_functionname”。
    3. __fastcall:编译后,函数名给修饰为“@functionname@nmuber”。
    4. 注:“functionname”为函数名,“number”为参数字节数。
    5. 注:函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。
  5. C++语言编译器函数名称修饰规则
    1. __stdcall:编译后,函数名被修饰为“?functionname@@YG******@Z”。
    2. __cdecl:编译后,函数名被修饰为“?functionname@@YA******@Z”。
    3. __fastcall:编译后,函数名被修饰为“?functionname@@YI******@Z”。
    4. 注:“******”为函数返回值类型和参数类型表。
    5. 注:函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。
    6. C语言和C++语言间如果不进行特殊处理,也无法实现函数的互相调用。

原文地址:http://blog.sina.com.cn/s/blog_701526f40100lcy6.html

【转】【C++】__stdcall、__cdcel和__fastcall三者的区别的更多相关文章

  1. C++知识回顾之__stdcall、__cdcel和__fastcall三者的区别

    __stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等. 调用协议常用场合 __stdcall: ...

  2. __stdcall、__cdcel和__fastcall三者的区别

    转自:https://www.cnblogs.com/huhewei/p/6080143.html 一.概述 __stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会 ...

  3. string、Empty和null三者的区别

    string.Empty和null三者的区别 本文转自  http://www.bitscn.com/pdb/dotnet/201003/181883.html 时间:2010-03-01 00:00 ...

  4. android Activity类中的finish()、onDestory()和System.exit(0) 三者的区别

    android Activity类中的finish().onDestory()和System.exit(0) 三者的区别 Activity.finish() Call this when your a ...

  5. 菜鸟,大牛和教主三者的区别(转自hzwer)

    菜鸟,大牛和教主,三者的区别 对菜鸟来说题目有三种:会算法且能AC的,会算法但不能AC的,不会做的 对大牛来说题目有两种:会做的,不会做的 对教主来说题目有两种:能AC的,数据有错的 菜鸟提交WA了, ...

  6. UIColor,CGColor,CIColor三者的区别和联系

    UIColor,CGColor,CIColor三者的区别和联系((转)) 最近看了看CoreGraphics的东西,看到关于CGColor的东西,于是就想着顺便看看UIColor,CIColor,弄清 ...

  7. /storage/sdcard, /sdcard, /mnt/sdcard 三者的区别

    原文地址: /storage/sdcard, /sdcard, /mnt/sdcard 三者的区别 - petercao - 博客园 http://www.cnblogs.com/bluestorm/ ...

  8. jQuery中,$.extend,$obj.extend和$.fn.extend三者的区别

    jQuery中,$.extend,$obj.extend和$.fn.extend三者的区别 现在做的一个项目,所使用的框架是基于jQuery扩展的,于是平时学了一下jQuery,了解到了它的扩展函数: ...

  9. String,StringBuilder,StringBuffer三者的区别

    参考   String,StringBuilder,StringBuffer三者的区别 这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面. 1.运行速度 首先说运行速度,或者说是执行速 ...

随机推荐

  1. Linux内核(2) - 分析内核源码如何入手(上)

    透过现象看本质,兽兽们无非就是一些人体艺术展示.同样往本质里看过去,学习内核,就是学习内核的源代码,任何内核有关的书籍都是基于内核,而又不高于内核的. 既然要学习内核源码,就要经常对内核代码进行分析, ...

  2. 仿<赶集生活>client启动动画效果

    demo下载地址: http://yun.baidu.com/s/1i3wqEMh 由于前几年csdn泄露password的事件,导致我的账号被拿去发广告文章了,联系了管理员帮我把几篇广告文删掉,可是 ...

  3. 深度学习图像标注工具VGG Image Annotator (VIA)使用教程

    VGG Image Annotator (VIA)是一款开源的图像标注工具,由Visual Geometry Group开发. 可以在线和离线使用,可标注矩形.圆.椭圆.多边形.点和线.标注完成后,可 ...

  4. NodeJS写日志_Log4js使用详解

    今天和大家分享一下NodeJS中写日志的一个常用第三方包:Log4js. 跟随主流Blog特色,先简单介绍下Log4js的基本信息.介绍Log4js之前,需要先说一下Log4***,Log4***是由 ...

  5. Jenkins 使用学习笔记

    3.1    Jenkins安装    2 3.1.1    Jenkins下载    2 3.1.2    Jenkins 安装    2 3.1.3    Jenkins 目录结构    3 3. ...

  6. Spring Boot 2.0 Intellij Idea 中图文详解打包成可执行Jar

    我们使用Spring Boot 2.0 创建好我们的项目后,我们一般需要打包,然后部署到服务器上. 打包步骤: 1. 选中项目,右键——> Open Module Settings. 2. 切换 ...

  7. 网络编程----------SOCKET编程实现简单的TCP协议

    首先我们须要大致了解TCP的几点知识: 1.TCP的特点:面向连接的可靠性传输 2.TCP的三次握手建立连接和四次挥手释放连接.但为什么TCP要三次握手建立连接呢? 答:由于两次握手无法保证可靠性.若 ...

  8. 在线升级java的版本

    真接rpm包安装javaxxxx.rpm 然后调整/etc/profile 如下: # tail -n /etc/profile JAVA_HOME=/usr/java/jdk1..0_45 PATH ...

  9. tornado日志使用详解

    1.需求 将http访问记录,程序自定义日志输出到文件,按天分割,保留最近30天的日志. 2.使用示例 init_logging("%s/QYK.%s.%s.log" % (log ...

  10. filebeat+kafka+SparkStreaming程序报错及解决办法

    // :: WARN RandomBlockReplicationPolicy: Expecting replicas with only peer/s. // :: WARN BlockManage ...