c/c++ stdcall cdel fastcall等函数调用约定说明
调用约定(Calling Conventions)是编程中定义函数如何接收参数、返回值以及如何管理堆栈的协议。主要的调用约定包括 __cdecl、__stdcall、__fastcall 和 __thiscall 等。下面将详细介绍这些调用约定的特点及其适用场景。
1. __cdecl 调用约定
 
- 定义:__cdecl是 C 语言的默认调用约定,适用于支持可变数量参数的函数。
- 参数传递: - 参数从右到左压入堆栈。
 
- 堆栈清理: - 由调用者负责清理堆栈。这意味着在函数调用后,调用者需要调整堆栈指针以移除参数。
 
- 返回值: - 返回值通常存储在 EAX 寄存器中。
 
- 使用场景: - 适合需要可变参数的函数,例如 printf。
 
- 适合需要可变参数的函数,例如 
示例
#include <stdio.h>void __cdecl my_function(int a, double b) {printf("a: %d, b: %f\n", a, b);
}int main() {my_function(10, 3.14);return 0;
}
2. __stdcall 调用约定
 
- 定义:__stdcall主要用于 Windows API,适合参数数量已知且固定的函数。
- 参数传递: - 参数同样从右到左压入堆栈。
 
- 堆栈清理: - 由被调用者负责清理堆栈,函数返回时会自动清理参数。
 
- 返回值: - 返回值通常存储在 EAX 寄存器中。
 
- 使用场景: - 主要用于 Windows API 和 DLL 函数。
 
示例
#include <windows.h>void __stdcall my_function(int a, double b) {// 进行一些操作
}int main() {my_function(10, 3.14);return 0;
}
3. __fastcall 调用约定
 
- 定义:__fastcall是一种较快的调用约定,使用寄存器传递前两个参数,可以减少堆栈操作。
- 参数传递: - 前两个参数通过寄存器(通常是 ECX 和 EDX)传递,其余参数从右到左压入堆栈。
 
- 堆栈清理: - 由调用者负责清理堆栈。
 
- 返回值: - 返回值通常存储在 EAX 寄存器中。
 
- 使用场景: - 适用于对性能有较高要求的场合,尤其是参数数量少且频繁调用的函数。
 
示例
void __fastcall my_function(int a, int b) {// 进行一些操作
}int main() {my_function(10, 20);return 0;
}
4. __thiscall 调用约定
 
- 定义:__thiscall是 C++ 中的默认调用约定,用于类的成员函数。
- 参数传递: - this指针通过 ECX 寄存器传递,其余参数从右到左压入堆栈。
 
- 堆栈清理: - 由调用者负责清理堆栈。
 
- 返回值: - 返回值通常存储在 EAX 寄存器中。
 
- 使用场景: - 主要用于 C++ 的成员函数,适合面向对象编程。
 
示例
class MyClass {
public:void __thiscall my_method(int a) {// 进行一些操作}
};int main() {MyClass obj;obj.my_method(10);return 0;
}
总结
| 调用约定 | 参数传递顺序 | 堆栈清理方式 | 适用场景 | 
|---|---|---|---|
| __cdecl | 从右到左压入堆栈 | 调用者清理堆栈 | 可变参数函数 | 
| __stdcall | 从右到左压入堆栈 | 被调用者清理堆栈 | Windows API 和 DLL继续深入探讨各种调用约定,特别是 __cdecl、__stdcall、__fastcall和__thiscall的具体特点、优缺点、以及在实际开发中的应用场景。 | 
5. 各调用约定的优缺点
1. __cdecl
 
-  优点: - 支持可变参数函数,可以处理像 printf这样的函数。
- 由于调用者清理堆栈,提供了灵活性。
 
- 支持可变参数函数,可以处理像 
-  缺点: - 每次调用后,调用者都需要清理堆栈,相对来说效率较低。
- 不适用于需要固定参数数量的情况下,可能导致参数处理上的复杂性。
 
2. __stdcall
 
-  优点: - 堆栈清理的责任在被调用者,简化了调用者的负担。
- 相较于 __cdecl,在非可变参数函数中,堆栈的操作更加高效。
 
-  缺点: - 不支持可变参数,不适合需要动态参数数量的函数。
- 在某些平台或编译器中可能不被广泛支持。
 
3. __fastcall
 
-  优点: - 通过寄存器传递参数,减少了堆栈操作,提高了函数调用的效率。
- 特别适合频繁调用的函数,能显著提高性能。
 
-  缺点: - 限制了能够通过寄存器传递的参数数量(通常只能前两个)。
- 代码的可移植性会受到影响,因为不同的平台对寄存器分配的处理可能不同。
 
4. __thiscall
 
-  优点: - 适用于 C++ 的类成员函数,this指针的传递使得成员函数调用更加高效。
- 通过寄存器传递 this指针,减少了堆栈的负担。
 
- 适用于 C++ 的类成员函数,
-  缺点: - 仅适用于 C++,对于其他语言或非成员函数不适用。
- 不同编译器可能对其实现有所不同,可能导致兼容性问题。
 
6. 实际应用中的选择
在实际开发中,选择合适的调用约定非常重要,以下是一些选择调用约定时的考虑因素:
-  函数的参数数量和类型: - 如果函数参数数量不固定,使用 __cdecl。
- 如果参数数量固定且不多,使用 __stdcall或__fastcall。
 
- 如果函数参数数量不固定,使用 
-  性能要求: - 对于性能敏感的应用,__fastcall是更优的选择,因为它减少了堆栈操作。
 
- 对于性能敏感的应用,
-  平台和编译器支持: - 确保所选调用约定在目标平台和编译器中被广泛支持,以避免兼容性问题。
 
-  代码可读性和维护性: - 选择调用约定时要考虑团队的熟悉程度和代码的可维护性。
 
7. 其他常见调用约定
除了上述提到的调用约定,以下是一些其他常见的调用约定:
-  __vectorcall:- 用于优化向量和浮点运算,参数通过寄存器传递,适合 SIMD 操作。
 
-  __regcall:- 允许更灵活的寄存器使用,通常用于特定的性能优化场景。
 
-  __usercall:- 允许用户自定义堆栈和寄存器的使用,不常用,主要用于高级优化。
 
8. 总结
调用约定在 C/C++ 编程中扮演着重要的角色,影响着程序的性能、可读性和兼容性。正确的调用约定选择能够有效提高程序的效率,减少错误和不必要的性能损失。开发者在编写代码时,应该根据具体的需求和上下文选择最合适的调用约定,以实现最佳的程序性能和可维护性。
相关文章:
c/c++ stdcall cdel fastcall等函数调用约定说明
调用约定(Calling Conventions)是编程中定义函数如何接收参数、返回值以及如何管理堆栈的协议。主要的调用约定包括 __cdecl、__stdcall、__fastcall 和 __thiscall 等。下面将详细介绍这些调用约定的特点及其适用场景。 1. __cdecl 调用约定 定义&…...
 
【ROS概述】概念及环境搭建
学习途径: 教程:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 课程视频:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 机器人体系 要完全实现一个机器人的系统研发,几乎是“全栈”开发,…...
 
MongoDB Shell 基本命令(三)生成学生脚本信息和简单查询
一、生成学生信息脚本 利用该脚本可以生成任意个学生信息,包括学号、姓名、班级、年级、专业、课程名称、课程成绩等信息,此处生成2万名学生,学生所有信息都是给定范围后随机生成。 生成学生信息后,再来对学生信息进行简单查询。…...
 
java核心技术点都有哪些
1. 面向对象编程(OOP) 核心概念:类、对象、继承、封装、多态。 比喻:面向对象编程就像是在搭建一个积木城堡。类(Class)是城堡的设计图纸,它定义了城堡的结构和功能;对象(…...
4404 - 提高:二分与三分:曲线(三分)
明明做作业的时候遇到了n个二次函数Si(x)=ax22+bx+c,他突发奇想设计了一个新的函数F(x)=max(Si(x)), i=1,2...n。 明明现在想求这个函数在[0,10000]的最小值,要求精确到小数点后四位四舍五入。 输入 输入包含T 组数据 (T<10) ,每组第一行一个整数 n(n≤10000) ,之后n行…...
 
软件工程--需求分析与用例模型
面向对象分析(ObjectOrientedAnalysis,简称OOA) 分析和理解问题域,找出描述问题域所需的类和对象,分析它们的内部构成和外部关系,建立独立于实现的OOA模型,暂时忽略与系统实现有关的问题。 主要使用UML中的以下几种图…...
 
预测房价学习
1. 实现函数来方便下载数据 import hashlib import os import tarfile import zipfile import requestsDATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)):"""下载一个DATA_HUB中…...
 
电脑无法上网,但是微信、QQ可以正常使用
这种情况一般是由于DNS服务器配置错误,或者已有的DNS服务器无法正常解析地址造成的。 按下winR打开运行,输入ncpa.cpl,点击确定。 在打开的网络连接窗口中找到对应的网卡,双击打开。一般有线网是“以太网”,无线网&am…...
 
C++11新特性(列表初始化与右值引用折叠与完美转发)
c11 列表初始化c98的{}c11的{}std::initializer_list 右值引用和移动语义左值和右值的概念左值引用和右值引用引用延长临时对象生命周期左值和右值的参数匹配左值引用的主要使用场景移动构造和移动赋值引用折叠完美转发 列表初始化 c98的{} 在C98中,大括号 {} 的使…...
 
基于SSH的物流运输货运车辆管理系统源码
基于经典的ssh(Spring Spring MVC Hibernate)框架与SaaS(软件即服务)模式,我们为运输企业与物流公司打造了一款开源且易用的车辆管理系统。 该系统主要包含以下核心模块: 档案管理 财务管理 借款管理 保…...
 
基于RabbitMQ,Redis,Redisson,RocketMQ四种技术实现订单延时关闭功能及其相关优缺点介绍(以12306为主题)
目录 1. 延迟关闭订单 1.1 订单延时关闭功能技术选型 1.1.1 定时任务 1.1.2 RabbitMQ 1.1.3 Redis 过期监听 1.1.4 Redisson 1.1.5 RocketMQ 1.2 RocketMQ订单延时关闭发送方实现 1.3 RocketMQ订单延时关闭的消费方实现 1. 延迟关闭订单 用户发起订单后,如…...
 
HarmonyOS ArkTS与C++数据类型转换
1. HarmonyOS ArkTS与C数据类型转换 本文介绍了C与TS各自数据类型与互相之间的数据类型转换,在需要使用C模块时可以快速上手对各种数据类型进行转换。 1.1. 概述 HarmonyOS的主力开发语言是ArkTS,也提供了C语言的支持,对于一些能力ÿ…...
 
腾讯云或阿里云centos7安装Redis,并解决端口无法访问的问题
问题背景 最近自建的网站JeecgFlow在云环境安装redis时候,出现端口无法远程进行访问。 浪费好了好久时间进行排查, 记录一下Redis在云环境centos7环境下如何安装,并且远程访问。 Redis安装 //安装c 用于编译redis yum install gcc-c//在/u…...
【小问题】距离估计和频率估计的方差下界推导出距离估计的方差下界
【1】OFDM Radar Algorithms in Mobile Communication Networks pp34 文章目录 1. 频率和距离之间的关系2. 计算 d ^ \hat{d} d^ 对 n ^ \hat{n} n^ 的导数3. 将频率的方差转化为距离的方差4. 从频率的 CRB 获得 var  [ n ^ ] \operatorname{var}[\hat{n}] var[n^]5. 将 …...
 
Selenium爬虫技术:如何模拟鼠标悬停抓取动态内容
介绍 在当今数据驱动的世界中,抓取动态网页内容变得越来越重要,尤其是像抖音这样的社交平台,动态加载的评论等内容需要通过特定的方式来获取。传统的静态爬虫方法难以处理这些由JavaScript生成的动态内容,Selenium爬虫技术则是一…...
 
Z-BlogPHP显示错误Undefined array key 0 (set_error_handler)的解决办法
今天打开博客的时候,意外发现页面,打开均显示错误:Undefined array key 0 (set_error_handler)。 博客程序采用的是Z-BlogPHP。百度了一圈没有找到解决办法,在官方论坛里也没找到解决办法。 于是开始自己排查原因。我服务器采用…...
java-实例化一个List,然后添加数据的方法详解
在Java中,实例化一个 List 并向其中添加数据非常简单。List 是一个接口,因此我们通常使用它的常见实现类 ArrayList 或 LinkedList。以下是一些常见的操作方法: ### 1. 使用 ArrayList 实例化并添加数据 java import java.util.ArrayList; …...
 
【Linux系统】Ubuntu的简单操作
什么是 Ubuntu? Ubuntu(乌帮图)是一个非洲词汇,它的意思是“人性对待他人”或“群在故我在”。Ubuntu发行版将Ubuntu精神带到软件世界之中。 目前已有大量各种各样基于GNU/Linux的操作系统,例如:Debian,SuSE,Gentoo,R…...
 
标准日志插件项目【C/C++】
博客主页:花果山~程序猿-CSDN博客 文章分栏:项目日记_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一,项目介…...
 
SpingBoot原理
SpingBoot原理 在前面十多天的课程当中,我们学习的都是web开发的技术使用,都是面向应用层面的,我们学会了怎 么样去用。而我们今天所要学习的是web后端开发的最后一个篇章springboot原理篇,主要偏向于底 层原理。 我们今天的课程…...
 
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
 
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
 
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
 
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
 
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
 
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
 
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
