如何让类的成员函数作为回调函数.doc

如何让类的成员函数作为回调函数.doc

ID:59357615

大小:39.50 KB

页数:5页

时间:2020-09-04

如何让类的成员函数作为回调函数.doc_第1页
如何让类的成员函数作为回调函数.doc_第2页
如何让类的成员函数作为回调函数.doc_第3页
如何让类的成员函数作为回调函数.doc_第4页
如何让类的成员函数作为回调函数.doc_第5页
资源描述:

《如何让类的成员函数作为回调函数.doc》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、如何让类的成员函数作为回调函数为什么类(class)的成员函(memberfunction)数不能作为回调函数(callbackfunction)首先来看看回调函数有怎样的特点。windows中,回调函都显式(explicit)使用CALLBACK修饰符(decorator)修饰(decorated)。实际上CALLBACK就是_stdcall参数传递方式(callingconvention)的宏定义。MSDN中对__stdcall做了如下定义:The__stdcallcallingconventionisusedtocallWin32APIfunctions.Thecalle

2、ecleansthestack,sothecompilermakesvarargfunctions__cdecl.Functionsthatusethiscallingconventionrequireafunctionprototype.ElementImplementationArgument-passingorderRighttoleft.Argument-passingconventionByvalue,unlessapointerorreferencetypeispassed.Stack-maintenanceresponsibilityCalledfunctionp

3、opsitsownargumentsfromthestack.Name-decorationconventionAnunderscore()isprefixedtothename.Thenameisfollowedbytheatsign(@)followedbythenumberofbytes(indecimal)intheargumentlist.Therefore,thefunctiondeclaredasintfunc(inta,doubleb)isdecoratedasfollows:_func@12Case-translationconventionNone其中心思想

4、是,__stdcall修饰的函数,参数从右至左依次压入堆栈,被调用者(callee)负责平衡堆栈(cleanalsocalled‘stackunwindinghandling’)。下面来看看类的成员函数有怎样的特点。在VC++中,所有类的成员函数在定义的时候都被隐式(implicit)定义为__thiscall参数传递方式。在MSDN中对__thiscall做了如下定义:The__thiscallcallingconventionisusedonmemberfunctionsandisthedefaultcallingconventionusedbyC++memberfunct

5、ionsthatdonotusevariablearguments.Under__thiscall,thecalleecleansthestack,whichisimpossibleforvarargfunctions.Argumentsarepushedonthestackfromrighttoleft,withthethispointerbeingpassedviaregisterECX,andnotonthestack,onthex86architecture.其中心思想是,__thiscall修饰的函数参数从右至左依次压入堆栈,被调用者负责平衡堆栈。之后是与C语言所有参

6、数传递方式均不相同的一点:成员函数所在类的this指针被存入ecx寄存器(这个特性只针对Intelx86架构)。对比之后,我们发现类成员函数不能作为回调函数的主要原因在于类成员函数使用__thiscal参数传递方式,因此需要调用者(caller)通过ecx寄存器提供类对象的指针。而回调函数使用__stdcall参数传递方式,不具备这个特点。如何让类成员函数成为回调函数根据第一节对回调函数与类成员函数各自特点的分析。不难发现,只要能想办法在类成员函数被调用之前设置好ecx寄存器,就能在__stdcall调用的基础上模拟出一个完好的__thiscall调用。如何提前设置ecx寄存器

7、呢?我们知道函数调用实际是通过汇编指令(oprand)’call函数地址’完成的。因此我们可以提供一个中间函数。当回调发生时,先调用中间函数,再在中间函数执行过程中设置ecx寄存器,当ecx设置好后jmp到类成员函数去(注意:这里是jmp不是call)。当执行到类的成员函数时,函数上下文(functioncontext)就和__thiscall所产生的完全一样了。如何制作这个中间函数呢?普通的函数是不行的。主要因为在vc++debug版本的代码中要使用ecx寄存器做堆栈溢出检测(stacko

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。