前言

看了网上各种关于stdcall和cdecl五花八门的解释,看了后让人初学者完全懵逼,甚至怀疑人生。

这里我用通俗易懂的方式,给大家讲解一下原理。

首先理解一个知识点,要知道前人为什么要这样做,而不那样做?优点?

stdcall和cdecl

都是函数调用约定之所以有不同的约定是由于历史原因,而且不同的编程语言有不同的调用约定,若要跨语言调用,则必须要了解函数调用约定。

函数调用约定

函数调用约定主要指,参数传递方式(从左到右还是从右到左),栈的清理方式(是由函数本身清理栈,还是由调用者清理栈)。

比如我编译一个程序,调用的一个别人编写库,如果说我们用同一种语言编写的,那么无所谓了,但是当我们使用的语言不一样,那就必须要考虑这个问题了。

stdcall

参数从右往左入栈,由函数自身清理栈。

cdecl

参数是从右往左入栈,由函数调用者清理栈。

我们写程序的时候,从不考虑栈的释放问题,什么临时变量什么的根本不用管,其实是编译器帮我们写了一段代码来处理了而已。从这里可以看出函数调用约定的重要性了,比如我们的一个库,里面的函数是由cdecl约定的(调用者清理栈),而我们的一个程序调用了这个库,使用了stdcall(函数自身清理栈)的调用方式来使用该函数,这个时候编译器不会生成清理栈的代码(编译器认为函数既然是stdcall调用,那么我就不用清理了吧),而函数自身也不清理。这不就出乱子了 么。

这里需要说明一下,为什么Windows下的API函数基本上都是stdcall(即WINAPI宏,函数自身清理栈)呢?而且推荐windows下都使用stdcall,假设我们多次调用了同一个系统API,你说我们是在每一个调用处都加清理栈的代码好,还是只函数自身处理栈就行?答案不是显而易见么,第二种方法可以省去不少空间,这不就是重用的思想么。

有人会问,为什么不统一起来,只用一种方式?那么为什么编程语言不是只有一种?当然,历史遗留问题以及优缺点的问题,没有完美的方法,只有合适的方法,况且还有其他的函数调用约定如__thiscall,__fastcall,__pascal,当然这不是本文的重点。

stdcall和cdecl函数调用约定详解相关推荐

  1. cdecl、stdcall、fastcall函数调用约定区别

    论函数调用约定 在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用这个函数.但是, ...

  2. 函数调用过程详解:函数栈帧的创建与销毁

    前言:我们在学习C语言的过程中,可以会产生很多疑问,比如: 局部变量是怎么创建的 为什么局部变量的值不做初始化就是随机值 函数是怎么传参的?传参的顺序是怎么样的? 形参和实参是什么关系? 函数调用是怎 ...

  3. iOS APP启动函数调用顺序~详解

    //联系人:石虎  QQ: 1224614774昵称:嗡嘛呢叭咪哄 一.OC调用 C++ 会为静态创建的对象生成初始化器,与静态语言不同,OC基于Runtime机制可以用类的名字来实例化一个类的对象. ...

  4. Python 函数调用父类详解

    Python super调用父类函数 文章目录 Python super调用父类函数 1. 介绍 2. 语法 3. 参数 4. 实例1 5. 实例2 1. 介绍 super() 函数是用于调用父类(超 ...

  5. java函数调用约定_函数调用约定 (cdecl stdcall)

    函数调用约定 (cdecl stdcall) 在 C 语言里,我们通过阅读函数声明,就知道怎么携带参数去调用函数,也能在函数体定义内使用这些参数.但是 CPU 并不直接完成函数调用的传参操作,这需要人 ...

  6. 【逆向工程】C/C++的反汇编表示详解(1)函数调用,栈平衡,变量与参数的内存布局

    很多人学完汇编,去看C/C++的反汇编就会很懵,发现单独看一条指令看的明明白白,但连在多条指令连在一起就不知道有什么作用了,如 push ebp mov ebp,esp sub esp,40h lea ...

  7. 详解C++中的函数调用和下标以及成员访问运算符的重载

    http://www.jb51.net/article/78436.htm 这篇文章主要介绍了详解C++中的函数调用和下标以及成员访问运算符,讲到了这些二元运算符使用的语法及重载,需要的朋友可以参考下 ...

  8. 函数调用的汇编语言详解

    一.基本概念 想要彻底的理解函数调用过程,先要明白一下几个概念. 1.栈 这里说的栈不是数据结构中的栈,而是计算机内存中的一块存储区,它的访问方式是"先进后出".大多数情况下,栈是 ...

  9. Linux高级专题详解--shell编程大全(shell变量,if语句,case语句,for循环,while循环,函数调用,数组,正则表达式,shell脚本三剑客--grep,sed,awk家族)

    shell编程 初始shell 程序 语言 编程 ---------------------------------- 语言 自然语言:汉语.英语 计算机语言:c语言.c++.(java php py ...

最新文章

  1. 如何搞30等角视图.斜45度说法不合理
  2. Java.util.Date.getTime()出现负数的问题
  3. [050] 微信公众平台开发入门视频教程已公布
  4. .8-Vue源码之AST(4)
  5. LeetCode 208. 实现 Trie (前缀树) —— 提供一套前缀树模板
  6. cryptojs vue 使用_VueJs里利用CryptoJs实现加密及解密
  7. 吃豆人动态模型创建---canvas
  8. Linux操作系统PS命令详细解析
  9. Mac下查看Git的安装目录
  10. HAOI2008 移动玩具
  11. Linux多线程编程入门
  12. Ubuntu安装Flash Player
  13. 一个被加入下载QQ盗号木马Trojan.PSW.QQPass.rie代码的网站
  14. 【STM8L】STM8L之按键中断
  15. 软考高项(信息系统项目管理师)计算题公式汇总
  16. CorelDRAW2022(CDR2022-64位),Win7 、Win10通用\免激活注册中文版安装图文教程
  17. 希腊神话:希腊众神 宙斯和赫拉
  18. Unity Scroll View在Clamped模式下无法移动
  19. 用自己的数据集训练C3D和tensorboard的使用
  20. 一、计算机网络概述之网络核心

热门文章

  1. SQL学习收获与心得
  2. position:absolute实现垂直居中
  3. linux关闭virbr0网卡
  4. windres.exe执行错误提示‘gcc‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。解决方法
  5. 计算机主机电源有哪些,电脑常见的电源故障有哪些
  6. 【教程】LaTeX 设置字体(不仅仅是字体大小,而且还有多种字体,比如 Comic Sans MS!!! fairly cool!)
  7. Spring配置文件中关于约束配置详解
  8. idea找不到spring配置文件
  9. Upstream Consistent Hash
  10. ILRuntime学习