本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9696081
建立时间:2004年12月20日




[c++]__stdcall比__cdecl有什么优点
原创空间,  软件技术

邢红瑞 发表于 2005/12/18 16:59:08

 Windows中可以指定的调用约定有三种:__fastcall, __stdcall, __cdecl。其区别可以从汇编代码中中看出。 1.__stdcall和__cdecl都是从右到左处理参数. 2.__fastcall的两个参数用ECX和EDX传递,其他的参数通过栈传递,其实也是从右到左入栈,寄存器要比栈快。 3.__cdecl需要在调用返回后由caller恢复栈指针,_fastcall和__stdcall由callee来恢复栈指针。类成员函数通常用ECX传递this指针,所以类成员函数是不能使用__fastcall调用约定的。而可变参数的函数只能用__cdecl调用约定,因为可变参数时,callee去恢复栈指针不大可能。另外三种调用约定生成的函数名也有所区别。 __stdcall是为了兼容windows,__stdcall调用约定相当于16位动态库中经常使用的PASCAL调用约定,在Windows中, WINAPI就是一个定义为__stdcall的宏,Windows.h支持该宏,它可以将输出函数翻译成适当的调用约定, VB、VFP等也采用这个约定。函数名修饰约定也有不同,对于c编译器,__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,格式为 _functionname@number。 __cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_functionname。__fastcall调用约定在输出函数名前加上一个 “@”符号,后面也是一个“@”符号和其参数的字节数,格式为@functionname@number。它们均不改变输出函数名中的自符大小写,这和PASCAL调用约定不同,PASCAL约定输出的函数名无任何修饰且全部大写。 总之, _stdcall将参数压栈是按C语言的顺序(从右到左),但与C 语言不同的是它是由被调用者将参数从栈中清除的。 __stdcall、__cdecl和__fastcall可以直接加在要输出的函数前,也可以在编译环境的Setting...\C/C++ \Code Generation项选择。当加在函数前的约定与编译环境中的约定不同时,必须加在输出函数前的添加约定。它们对应的命令行参数分别为/Gz、/Gd和/Gr。在VC7.1及以前的编译器中,默认的编译选项是/Gd,如果没有指定调用约定,那么编译器就使用 __cdecl。而在VS2005中,默认的编译选项变成了/Gz,但是对非变参的函数,使用__stdcall调用约定。


阅读全文(4993) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.078 second(s), page refreshed 144753256 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号