- 1、本文档共7页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
函数的调用约定方式及函数的名称修饰符.pdf
几乎每种编程语言都有函数的概念,而作为函数,就一定有参数的概念;
一般来说,参数的传递是通过栈来实现的,栈是一种先入后出的数据结构,使用Push()把参数压
入栈中,使用Pop()把参数弹出栈,而且Push()和Pop()必须成对出现。
现在称为标准调用的就是PASCAL 语言的调用方式:反序压栈,正序出栈;这样做的确有好处, 因
为压栈行为是编译器编译好的(编译时行为),虽然麻烦,但是只在编译阶段做一次,而出栈行为
是程序实际运行时的调用行为(运行时行为),需要反复多次执行,使用正序的参数(正序出栈),
对被调函数来说,处理上方便不少;
而Windows 使用的调用方式跟PASCAL 语言的调用方式是一样的,所以, 以前老的C 程序员编
写Windows 程序时需要使用关键字PASCAL 来明确指出使用PASCAL 的调用规则,现在一般不
再使用PASCAL 关键字了,而使用__stdcall 说明符,表示使用的是标准调用;
使用C/C++语言开发软件的程序员经常碰到这样的问题:
有时候是程序编译没有问题,但是链接的时候总是报告函数不存在(经典的LNK 2001 错误),
有时候是程序编译和链接都没有错误,但是只要调用库中的函数就会出现堆栈异常。这些现
象通常是出现在C 和C++ 的代码混合使用的情况下或在C++程序中使用第三方的库的情况下
(不是用 C++语言开发的) ,其实这都是函数调用约定(Calling Convention) 和函数名修饰
(Decorated Name)规则惹的祸。
函数调用约定方式决定了函数参数入栈的顺序,是由调用者函数还是被调用函数负责清除栈
中的参数等问题,而函数名修饰规则决定了编译器使用何种名字修饰方式来区分不同的函数,
如果函数之间的调用约定不匹配或者名字修饰不匹配就会产生以上的问题。本文分别对 C
和 C++这两种编程语言的函数调用约定和函数名修饰规则进行详细的解释,比较了它们的
异同之处,并举例说明了以上问题出现的原因。
*******************************************************************************
一、函数的调用约定方式(Calling Convention):
有很多种方式,常见的有__cdecl 、__stdcall 、__fastcall,C++ 的编译器还支持__thiscall 方式,不少
的C/C++编译器还支持naked call 方式;
*******************************************************************************
1.__cdecl 方式(编译器的命令行参数是/Gd):
__cdecl 是C/C++编译器默认的函数调用约定;
所有非C++成员函数和那些没有用__stdcall 或__fastcall 声明的函数都默认是__cdecl 方式。
函数参数按照从右向左的顺序入栈,函数调用者负责清除栈中的参数。由于每次函数调用
都要由编译器产生清除/ 还原堆栈的代码, 所以使用__cdecl 方式编译出来的程序比使用
__stdcall 方式编译出来的程序要大很多,但是__cdecl 调用方式是由调用者函数负责清空栈中
的函数参数,所以,__cdecl 方式支持可变参数, 比如 printf 和 Windows 的 API wsprintf 就是
__cdecl 调用方式;
对于C 函数,__cdecl 方式的名字修饰符约定是在函数名称前面添加一个下划线;
对于C++ 函数,除非特别使用extern C,C++函数使用不同的名字修饰符;
2.__stdcall 方式(编译器的命令行参数是/Gz):
_stdcall 是Pascal 程序的缺省调用方式,通常用于Win32 Api 中, 大多数Windows 的API 也
是__stdcall 调用约定。
__stdcall 函数调用约定将函数参数从右向左入栈,除非使用指针或引用类型的参数,所有
参数采用传值方式传递,由被调用函数负责清除栈中的参数。
对于 C 函数,__stdcall 的名称修饰方式是在函数名称前面添加下划线,在函数后面添加@符号
和函数参数所占用的内存字节大小;例如: _function_name@number;
3.__fastcall 方式(编译器的命令行参数是/Gr):
__fastcall 函数调用约定在可能的情况下
您可能关注的文档
- 关于泊松分布的一点注记.pdf
- 关于洛仑兹力相对性的讨论.pdf
- 关于激光刻痕处理取向硅钢的时效性质的研究.pdf
- 关于移动平均法的探讨.pdf
- 关于第二部中江天性格走向的必然因素.pdf
- 关于编写_资治通鉴_的几个问题.pdf
- 关于诚信的理论思考.pdf
- 关于重庆抗旱减灾的思考.pdf
- 关于麦克斯韦速率分布随温度变化的探讨.pdf
- 关注_班级边缘人_初中生班级归属感的缺失与培养_王秋芳.pdf
- 2024年江西省寻乌县九上数学开学复习检测模拟试题【含答案】.doc
- 2024年江西省省宜春市袁州区数学九上开学学业水平测试模拟试题【含答案】.doc
- 《GB/T 44275.2-2024工业自动化系统与集成 开放技术字典及其在主数据中的应用 第2部分:术语》.pdf
- 中国国家标准 GB/T 44275.2-2024工业自动化系统与集成 开放技术字典及其在主数据中的应用 第2部分:术语.pdf
- GB/T 44285.1-2024卡及身份识别安全设备 通过移动设备进行身份管理的构件 第1部分:移动电子身份系统的通用系统架构.pdf
- 《GB/T 44285.1-2024卡及身份识别安全设备 通过移动设备进行身份管理的构件 第1部分:移动电子身份系统的通用系统架构》.pdf
- 中国国家标准 GB/T 44285.1-2024卡及身份识别安全设备 通过移动设备进行身份管理的构件 第1部分:移动电子身份系统的通用系统架构.pdf
- GB/T 44275.11-2024工业自动化系统与集成 开放技术字典及其在主数据中的应用 第11部分:术语制定指南.pdf
- 中国国家标准 GB/T 44275.11-2024工业自动化系统与集成 开放技术字典及其在主数据中的应用 第11部分:术语制定指南.pdf
- 《GB/T 44275.11-2024工业自动化系统与集成 开放技术字典及其在主数据中的应用 第11部分:术语制定指南》.pdf
文档评论(0)