__stdcall in c++ builder
VC默认为__stdcall,
BCB默认为__cdecl,
Delphi默认为__fastcall。
由于BCB使用Delphi的VCL库,
所以也必须使用__fastcall。
关键字 | 调用规则 | 参数传递方向 | 返回 | 参数寄存器 | 堆栈的清除 |
__cdecl | C调用规则 | 从右向左 | EAX | 无 | 调用者 |
__fastcall | 寄存器 | 从左向右 | EAX | EAX、EBX、ECX | 被调用者 |
__stdcall | Win32标准 | 从右向左 | EAX | 无 | 被调用者 |
__pascal | Pascal | 从左向右 | EAX | 无 | 被调用者 |
__msfastcall | Ms寄存器 | 从右向左 | EAX/EDX | ECX、EDX | 被调用者 |
摘自《面向状态的程序设计与C++ Builder》第四章第一节 Lewolf著
1.4.1 __cdecl、_cdecl、cdecl关键字
这是在C++ Builder中特有的关键字,__cdecl、_cdecl、cdecl可以用来修饰变量或者函数,其含义是指定的变量或者函数使用C语言的调用规则和命名规则。在C++ Builder中C调用规则是缺省的设置,可以通过Project的Option菜单在Advanced Compiler标签中来改变缺省设置。
对于C命名规则的变量或函数,具有大小些敏感、编译后变量名称前下划线前导符,这与Pascal语言是不一样的。对于函数,C调用规则要求使用堆栈传递参数,参数传递的顺序为自右向左依次压入堆栈,由调用者自行清除堆栈,C调用规则允许向函数传递不定参数,但这种调用方式系统需要更多的开销来完成参数的匹配,除非特殊用途一般尽量不要使用,这种调用方式最典型的例子是控制台程序中的main函数,程序运行时可以不带参数,也可以带多个参数。
在一个独立的程序中,采用那种调用规则或者命名规则影响并不十分大,但是在多种语言混合编程,或者编写带有数据输出或函数输出的可执行模块(可执行文件和动态链接库)时,命名规则和调用规则显得尤为重要,使用不当则可能导致程序无法正常运行,甚至使系统崩溃。
__cdecl、_cdecl、cdecl的使用语法如下:
cdecl <data/function definition> ;
_cdecl <data/function definition> ;
__cdecl <data/function definition> ;
例如:
int cdecl I; //编译后标识符为“_I”
void __cdecl Fun(); //编译后函数名为“_Fun”
1.4.2 __fastcall、_fastcall关键字
__fastcall和_fastcall也是C++ Builder中特有的关键字,只能用于修饰函数,其作用是指定函数使用“寄存器”调用规则,使用语法如下:
return-type _fastcall function-name(parm-list)
return-type __fastcall function-name(parm-list)
例如:
void __fastcall GetName(int Index);
使用“寄存器”调用规则的函数,其参数传递顺序为自左向右依次传递,并且将前三个参数尽可能的使用EAX、EBX、ECX这三个寄存器传递,对于前三个参数中浮点类型、结构类型等超过四个字节的变量,和第四个及以后的参数则采用堆栈来传递,因此采用“寄存器”调用规则的函数只能传递固定数量的参数。
在C++ Builder中,所有属于VCL的成员函数,必须是__fastcall类型,编译器将“寄存器”调用规则和C调用规则、Pascal调用规则以及Win32的标准等其它调用规则是同等对待的,因此__fastcall关键字不能和__cdecl、__pascal、__stdcall等关键字联合使用,也不能和__export关键字同时使用(实际上使用__fastcall规则的函数是允许输出的,只是这种调用规则编写的dll或可执行模块只能被C++ Builder或者Delphi开发的程序载入并调用输出的函数)。
被指定为“寄存器”调用的函数会在编译时被冠以前导符@,这将使得C及C++的函数命名过于混乱,但是这种调用规则有很高的执行效率,因此在C++ Builder中几乎所有VCL的成员函数都使用这种调用规则。
但是__fastcall和_fastcall是C++ Builder之前的C++编译器所没有的调用规则,为了保证兼容性,可以使程序连接以前版本的编译器生成的库文件,C++ Builder提供了-VC命令行选项,缺省状态下,该选项是关闭的,当需要时,可以通过命令行编译并选择-VC选项。
1.4.3 __msfastcall、__msreturn关键字
__msfastcall和__msreturn也是C++ Builder中特有的关键字,使用这两个关键字可以为程序提供和Microsoft兼容的“寄存器调用”规则以及和Microsoft兼容的函数返回的规则。
被__msfastcall修饰的函数,其参数传递顺序为前两个参数如果长度小于4字节,则分别使用ECX和EDX寄存器传递,其余的参数和前两个不能使用寄存器传递的参数则按照从右向左的顺序通过堆栈来传递,堆栈由被调用函数负责清除。
__msreturn是使用Microsoft兼容的“寄存器调用”返回规则,在这种返回规则中,返回值的长度在4~8个字节时,将采用EAX/EDX寄存器返回函数值。
1.4.4 __pascal、_pascal、pascal关键字
__pascal、_pascal、pascal关键字表示一个变量或者函数遵循Pascal的调用和命名规则。
在Pascal的命名规则中,对大小写并不敏感,而且不象C调用规则,会在变量和函数明成前面加前导符。Pascal调用规则中,参数的传递是按照从左到右的顺序依次压入堆栈,并且由被调用函数自行清除堆栈。
Pascal调用规则破坏了C语言的本身的调用体系,同时也带来了更多的灵活性,被表示为__pascal调用规则的函数,编译后的目标文件中,名称会被全部转换为大写字母,在Pascal语言中,过程和函数的书写是对大小些不敏感的,但是在C++ Builder中采用Pascal调用规则的函数,在C++源文件中仍然需要遵循C语言中对大小些必须严格一致的要求,Pascal调用规则的大小写不敏感性只能体现在动态链接库、或者输出、输入函数以及数据的时侯。也正是这样的原因,对一些采用Object Pascal编写的第三方控件或者书写不是很规范的Pascal程序代码,使用C++ Builder编译的时候,会出现找不到函数原型的错误,实际上可能只是程序中函数名称的大小些不一致造成的。
1.4.5 __stdcall、_stdcall关键字
在Windows程序设计中,有一种Win32的标准调用规则,基本上所有的Windows API函数都采用了这种Win32的标准调用规则,在讲__declspec(nothrow)关键字时的例子,其中宏定义就是C++ Builder中winuser.h宏定义。Win32标准调用在C++ Builder中以__stdcall、_stdcall关键字来标识。
在__stdcall、_stdcall调用规则中,函数的参数是按照从右向左的顺序依次压入堆栈,所有的参数均采用堆栈传递,而且是被调用函数负责清除堆栈。在参数的传递顺序上,Win32标准调用规则和C调用规则一样,从右向左,但和C调用规则不同的是,Win32的标准调用要求调用者必须严格按照被调用函数的参数数量及类型进行参数传递。
关于C++ Builder中函数调用规则以及命名规则的详细内容,读者参考相关书籍,这里不做过多讲解,下表给出了C++ Builder中几种调用规则的一个简单比较,具有汇编语言基础的读者可以参考本书光盘中相关代码自行分析区别。
关键字 调用规则 参数传递方向 返回 参数寄存器 堆栈的清除
__cdecl C调用规则 从右向左 EAX 无 调用者
__fastcall 寄存器 从左向右 EAX EAX、EBX、ECX 被调用者
__stdcall Win32标准 从右向左 EAX 无 被调用者
__pascal Pascal 从左向右 EAX 无 被调用者
__msfastcall Ms寄存器 从右向左 EAX/EDX ECX、EDX 被调用者
__stdcall in c++ builder相关推荐
- C++ Builder创建和调用dll中的资源
程序开发中经常会用到一些图标.图片.光标.声音等,我们称它们为资源(Resource).当多个窗口用到同样的资源时,可以将这些公共的资源放到一个dll文件里调用,这样,由于定位资源比在磁盘中定位文件花 ...
- 怎样在C++Builder中创建使用DLL
动态链接库(DLL)是Windows编程常遇到的编程方法,下面我就介绍一下在 BCB (C++Builder下简称BCB) 中如何创建使用DLL和一些技巧. 一.创建: 使用BCB File|NEW建 ...
- 在 C++Builder 工程里调用 DLL 函数
调用 Visual C++ DLL 给 C++Builder 程序员提出了一些独特的挑战.在我们试图解决 Visual C++ 生成的 DLL 之前,回顾一下如何调用一个 C++Builder 创建的 ...
- c++builder 6.0中OnCliked= fun实现的原理
C++builer 6.0中使用委托类型,使用非常的方便 . Member Function Pointers and the Fastest Possible C++ Delegates Don C ...
- 使用微信PC端的截图dll库实现微信截图功能(C++ Builder实现)
使用微信PC端的截图dll库实现微信截图功能(C++ Builder实现) 网上有很多文章说"使用微信PC端的截图dll库实现微信截图功能",我用node实现截图也要用一下,于是找 ...
- BCB(C++ Builder)创建动态库(DLL,接口导出和调用),动态加载DLL
以前没有封装dll动态库,接触新的工作之后需要用,折腾了一整天,终于搞定了 毕竟是生手,就简单分析注意点和遇到的一些问题及解决方案: (1)首先准备要生成DLL的工程. (1.1)我用的是BCB(C+ ...
- C++Builder 资料库 (转载)
C++Builder 资料库 2005-03-03 15:14 13115人阅读 评论(3) 收藏 举报 1.怎样在C++Builder中创建使用DLL 2.用C++Bulider在WIN.INI中保 ...
- C++Builder 资料库
转自: http://blog.csdn.net/chiengod/article/details/309466 1.怎样在C++Builder中创建使用DLL 2.用C++Bulider在WIN. ...
- C++ Builder 杂项
1.怎样在C++Builder中创建使用DLL 2.用C++Bulider在WIN.INI中保存信息 3.如何在C++Builder中检测硬件 4.C++Builder如何响应消息及自定义消息 5.利 ...
最新文章
- element ui表格点击整行选择_element-ui实现动态表头的表格问题汇总
- IOS中UIActionSheet使用方法详解
- Mysql 中获取刚插入的自增长id的值
- 火狐SEO插件:查询网站收录与外链的火狐油猴脚本工具
- how is my appointment opened in HCP
- C#让TopMost窗体弹出并置顶层但不获取当前输入焦点的终极办法
- JAVAWEB入门tomcat服务器配置
- 飞鸽传书 扩散全身的
- 有没有可以干一辈子的工作?
- pe修改服务器2003密码,一文教你3分钟搞定忘记的windows密码
- 《斩魔问道》突破传统玩法,实时强战PK,爆裂高清画质的仙侠手游巨作
- 《天龙八部》地形研究-1
- 【知识图谱】知识图谱数据构建的“硬骨头”,阿里工程师如何拿下?深度学习在知识图谱构建中的应用。
- SpringBoot项目启动Disconnected from the target VM
- bzip2: Data integrity error when decompressing--apt-get update
- 盖茨18年首富成就福布斯神话 揭示盖茨不为人知的秘密
- oo 浏览文件服务器,文件服务器的配置.docx
- 高频前端面试题汇总之计算机网络篇
- STM8L低功耗设置,深坑。。。
- 华为畅享10s值得买吗_达人测评华为畅享10e和10S哪个好??有区别吗?实情爆料细节...
热门文章
- 横州中学理科2021高考成绩查询,2021年横县高考状元名单资料,今年横县高考状元多少分...
- k2677场效应管参数引脚_场效应管参数大全2.doc
- document.body.offsetWidth 网页可见区域高宽,offset、client、scroll使用方法详解,页面位置距离
- switchyomega规则列表备份_求人不如求己,自己动手写一个CSDN博客备份小工具?...
- 博达交换机镜像端口配置_“量身定制”的轨道交通工业以太网交换机,RT FORUM2019春季大会智慧解决方案12...
- 图像压缩算法动态规划c语言,图像压缩算法 动态规划
- 利用反射光电管 ITR9909 制作节能信标光电感应开关
- 航天智慧物流南北分区赛通知
- 更大的工字型电感作为150kHz导航信号接收天线
- 第十五届全国大学生智能车竞赛安徽赛区比赛报名信息