stdcall和cdecl函数调用约定详解
前言
看了网上各种关于stdcall和cdecl五花八门的解释,看了后让人初学者完全懵逼,甚至怀疑人生。
这里我用通俗易懂的方式,给大家讲解一下原理。
首先理解一个知识点,要知道前人为什么要这样做,而不那样做?优点?
stdcall和cdecl
都是函数调用约定之所以有不同的约定是由于历史原因,而且不同的编程语言有不同的调用约定,若要跨语言调用,则必须要了解函数调用约定。
函数调用约定
函数调用约定主要指,参数传递方式(从左到右还是从右到左),栈的清理方式(是由函数本身清理栈,还是由调用者清理栈)。
比如我编译一个程序,调用的一个别人编写库,如果说我们用同一种语言编写的,那么无所谓了,但是当我们使用的语言不一样,那就必须要考虑这个问题了。
stdcall
参数从右往左入栈,由函数自身清理栈。
cdecl
参数是从右往左入栈,由函数调用者清理栈。
我们写程序的时候,从不考虑栈的释放问题,什么临时变量什么的根本不用管,其实是编译器帮我们写了一段代码来处理了而已。从这里可以看出函数调用约定的重要性了,比如我们的一个库,里面的函数是由cdecl约定的(调用者清理栈),而我们的一个程序调用了这个库,使用了stdcall(函数自身清理栈)的调用方式来使用该函数,这个时候编译器不会生成清理栈的代码(编译器认为函数既然是stdcall调用,那么我就不用清理了吧),而函数自身也不清理。这不就出乱子了 么。
这里需要说明一下,为什么Windows下的API函数基本上都是stdcall(即WINAPI宏,函数自身清理栈)呢?而且推荐windows下都使用stdcall,假设我们多次调用了同一个系统API,你说我们是在每一个调用处都加清理栈的代码好,还是只函数自身处理栈就行?答案不是显而易见么,第二种方法可以省去不少空间,这不就是重用的思想么。
有人会问,为什么不统一起来,只用一种方式?那么为什么编程语言不是只有一种?当然,历史遗留问题以及优缺点的问题,没有完美的方法,只有合适的方法,况且还有其他的函数调用约定如__thiscall,__fastcall,__pascal,当然这不是本文的重点。
stdcall和cdecl函数调用约定详解相关推荐
- cdecl、stdcall、fastcall函数调用约定区别
论函数调用约定 在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用这个函数.但是, ...
- 函数调用过程详解:函数栈帧的创建与销毁
前言:我们在学习C语言的过程中,可以会产生很多疑问,比如: 局部变量是怎么创建的 为什么局部变量的值不做初始化就是随机值 函数是怎么传参的?传参的顺序是怎么样的? 形参和实参是什么关系? 函数调用是怎 ...
- iOS APP启动函数调用顺序~详解
//联系人:石虎 QQ: 1224614774昵称:嗡嘛呢叭咪哄 一.OC调用 C++ 会为静态创建的对象生成初始化器,与静态语言不同,OC基于Runtime机制可以用类的名字来实例化一个类的对象. ...
- Python 函数调用父类详解
Python super调用父类函数 文章目录 Python super调用父类函数 1. 介绍 2. 语法 3. 参数 4. 实例1 5. 实例2 1. 介绍 super() 函数是用于调用父类(超 ...
- java函数调用约定_函数调用约定 (cdecl stdcall)
函数调用约定 (cdecl stdcall) 在 C 语言里,我们通过阅读函数声明,就知道怎么携带参数去调用函数,也能在函数体定义内使用这些参数.但是 CPU 并不直接完成函数调用的传参操作,这需要人 ...
- 【逆向工程】C/C++的反汇编表示详解(1)函数调用,栈平衡,变量与参数的内存布局
很多人学完汇编,去看C/C++的反汇编就会很懵,发现单独看一条指令看的明明白白,但连在多条指令连在一起就不知道有什么作用了,如 push ebp mov ebp,esp sub esp,40h lea ...
- 详解C++中的函数调用和下标以及成员访问运算符的重载
http://www.jb51.net/article/78436.htm 这篇文章主要介绍了详解C++中的函数调用和下标以及成员访问运算符,讲到了这些二元运算符使用的语法及重载,需要的朋友可以参考下 ...
- 函数调用的汇编语言详解
一.基本概念 想要彻底的理解函数调用过程,先要明白一下几个概念. 1.栈 这里说的栈不是数据结构中的栈,而是计算机内存中的一块存储区,它的访问方式是"先进后出".大多数情况下,栈是 ...
- Linux高级专题详解--shell编程大全(shell变量,if语句,case语句,for循环,while循环,函数调用,数组,正则表达式,shell脚本三剑客--grep,sed,awk家族)
shell编程 初始shell 程序 语言 编程 ---------------------------------- 语言 自然语言:汉语.英语 计算机语言:c语言.c++.(java php py ...
最新文章
- 如何搞30等角视图.斜45度说法不合理
- Java.util.Date.getTime()出现负数的问题
- [050] 微信公众平台开发入门视频教程已公布
- .8-Vue源码之AST(4)
- LeetCode 208. 实现 Trie (前缀树) —— 提供一套前缀树模板
- cryptojs vue 使用_VueJs里利用CryptoJs实现加密及解密
- 吃豆人动态模型创建---canvas
- Linux操作系统PS命令详细解析
- Mac下查看Git的安装目录
- HAOI2008 移动玩具
- Linux多线程编程入门
- Ubuntu安装Flash Player
- 一个被加入下载QQ盗号木马Trojan.PSW.QQPass.rie代码的网站
- 【STM8L】STM8L之按键中断
- 软考高项(信息系统项目管理师)计算题公式汇总
- CorelDRAW2022(CDR2022-64位),Win7 、Win10通用\免激活注册中文版安装图文教程
- 希腊神话:希腊众神 宙斯和赫拉
- Unity Scroll View在Clamped模式下无法移动
- 用自己的数据集训练C3D和tensorboard的使用
- 一、计算机网络概述之网络核心
热门文章
- SQL学习收获与心得
- position:absolute实现垂直居中
- linux关闭virbr0网卡
- windres.exe执行错误提示‘gcc‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。解决方法
- 计算机主机电源有哪些,电脑常见的电源故障有哪些
- 【教程】LaTeX 设置字体(不仅仅是字体大小,而且还有多种字体,比如 Comic Sans MS!!! fairly cool!)
- Spring配置文件中关于约束配置详解
- idea找不到spring配置文件
- Upstream Consistent Hash
- ILRuntime学习