社区
硬件/系统
帖子详情
今天看了回调函数发现有个__stdcall与cdecl 非常不解求助!!!
mihonghang
2005-07-11 11:45:20
rt
...全文
348
4
打赏
收藏
今天看了回调函数发现有个__stdcall与cdecl 非常不解求助!!!
rt
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
oyljerry
2005-07-12
打赏
举报
回复
__stdcall通用调用约定
__cdecl vc默认的调用约定
蒋晟
2005-07-12
打赏
举报
回复
cdecl 参数从右至左入栈,函数负责清除堆栈,返回值的处理如下
VC:
除了浮点数之外的基本类型和大小小于或者等于8字节的结构根据大小不同保存在EAX或者EAX:EDX组合中
浮点数和双精度数保存在fp0中
大小超过8字节的,或者有构造函数、析构函数、虚函数之一的结构或者类在内存中返回。返回值在内存中时调用者会分配对应大小的内存,并且将其作为隐含的第一个参数传递。函数调用之后调用者负责清除这块内存。
其它:
某些编译器在按值传递有析构函数的类和结构时会强制转换成按地址传递。某些编译器会把所有返回值强制放在内存中
stdcall
同cdecl,但是函数调用者负责清除堆栈
thiscall
VC:
同stdcall,但是this指针在ECX中传递,类和结构类型的返回值强制放在内存中。如果函数参数的数目可变,那么同cdecl,但是this指针成为隐含的第一个参数。
其它:
同stdcall,但是this指针成为隐含的第一个参数。
fastcall
除了开始两个大小小于4字节的参数会通过寄存器传递之外,其它同cdecl。
64位平台上调用约定有所变化,但是我没有做过这方面的研究。
参考文章
http://support.microsoft.com/default.aspx/kb/100832
http://p5.club.163.com/viewArticleByWWW.m?boardId=clanguage&articleId=clanguage_104ffea50e53121&boardOffset=0
http://www.codeproject.com/cpp/FastDelegate.asp
newbiestar
2005-07-12
打赏
举报
回复
同楼上
cdecl是C语言里面函数调用使用得最多的协议(可以说绝大多数都是这个,Unix/Linux下面清一色都是这个……),主要特性是使用eax寄存器保存返回值(通常对于比较小的类型如此),调用方清栈(所以可以支持变参函数),另外它也是C/C++默认的调用协议(也就是说不额外声明的话,默认就是cdecl的)
stdcall是Windows API标准的调用方式,所有的Windows API都是靠这个调用协议,好像一般callback也都是用这个的……
qrlvls
2005-07-11
打赏
举报
回复
调用约定,使用不同的调用约定,则传递参数的顺序和方式会不同,例如多个参数的入栈顺序会不同,而象__fastcall约定会尽可能的使用寄存器传递参数
因此如果一个__stdcall声明的函数通过__cdecl的方式去调用就会出现错误
__
std
call和__
cd
ecl
的区别
__
std
call和__
cd
ecl
是两种函数名字修饰。(注意是连续的两个下划线)Windowswindows上不管是C还是C++,默认使用的都是__
std
call方式。不论__
std
call还是__
cd
ecl
函数参数都是从可向左入栈的,并且由调用者完成入栈操作。对于__
std
call方式被调用者自身在函数返回前清空堆栈;而__
cd
ecl
则由调用者维护内存堆栈,所以调用者函数生成的汇编代码比前一种方式
关于函数调用方式__
std
call和__
cd
ecl
详解
std
call
cd
ecl
关于__
std
call和__
cd
ecl
调用方式的理解
__
std
call和__
cd
ecl
都是函数调用约定关键字,先给出这两者的区别,然后举实例分析: __
std
call:参数由右向左压入堆栈;堆栈由函数本身清理。 __
cd
ecl
:参数也是由右向左压入堆栈;但堆栈由调用者清理。 另外,这两者在同一名字修饰约定下,编译过后变量和函数的名字也不一样,具体见另一博文:名字修饰约定extern "C"与extern "C+
函数调用方式__
std
call和__
cd
ecl
详解
**名称修饰**:除了函数名前缀`_`之外,在Visual C++中,函数名后还会附加一个`@`符号,后面跟着参数的总字节数,例如`_MyFunction@16`表示有四个字节的参数(32位系统中,每个参数通常占4字节,共四个参数)。- **名称修饰**:在Visual C++等编译器中,函数名通常会被编译器加上前缀`_`,对于C++成员函数还会加上类名修饰。- **参数传递顺序**:与`__
cd
ecl
`相同,参数也是从右到左入栈。- **默认情况**:这是C和C++程序的默认调用约定。
回调函数
引发__
cd
ecl
和__
std
call错误
由于项目要包含其他库文件,需要注册
回调函数
,结果注册时报错 cannot convert from 'void (__
cd
ecl
*)(int *)' to 'void (__
std
call *)(int *)' 这就奇怪了,明明函数定义都是符合格式怎么会出现这个错, 最后解决就是在函数命名前加一个__
std
call void __
std
call my_fun(int *); 原因在于编译器默认是使用__
cd
ecl
...
硬件/系统
2,643
社区成员
17,229
社区内容
发帖
与我相关
我的任务
硬件/系统
VC/MFC 硬件/系统
复制链接
扫一扫
分享
社区描述
VC/MFC 硬件/系统
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章