博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
以类的成员函数作为Windows callback函数
阅读量:4109 次
发布时间:2019-05-25

本文共 1584 字,大约阅读时间需要 5 分钟。

[注:摘自《深入浅出MFC》第6章浅出MFC程序设计(P.298)]

    首先我要很快地解释一下什么是callback函数。凡是由你设计而却由Windows系统调用的函数,统称为callback函数。这些函数都有一定的类型,以配合Windows的调用操作。

    某些Windows API函数会要求以callback函数作为其参数之一,这些API,例如SetTimer、LineDDA、EnumObjects。通常这种API会在进行某种行为之后或满足某种状态之时调用该callback函数。下面示范的EnumObjects是在发现某个Device Context的GDI object符合我们的指定类型时,调用callback函数。

    好,现在我们要讨论的是,什么函数有资格在C++程序中作为callback函数?这个问题的背后是:C++程序中的callback函数有什么特别的吗?为什么要特别提出讨论?

    是的,特别之处在于,C++编译器为类成员函数多准备了一个隐藏参数(在程序代码中看不到),这使得函数类型与Windows callback函数的默认类型不符。

    假设我们有一个CMyClass如下:

class CMyClass {private:    int nCount;    int CALLBACK _export        EnumObjectsProc(LPSTRlpLogObject, LPSTR lpData);public:    void enumIt(CDC& dc);}

void CMyClass::enumIt(CDC& dc){	// 注册callback函数	dc.EnumObjects(OBJ_BRUSH, EnumObjectsProc, NULL);}C++编译器针对CMyClass::enumIt实际做出来的代码相当于:void CMyClass::enumIt(CDC& dc){	CDC::EnumObjects(OBJ_BRUSH, EnumObjectsProc, NULL, (CDC *)&dc);}

    你所看到的最后一个参数,(CDC *)&dc,其实就是this指针,类成员函数靠着this指针才得以抓到正确的数据。你要知道,内存中只会有一份类成员函数,但却可能有许多份类的成员变量——每个对象拥有一份。

    C++以隐含的this指针指出正确的对象。当你这么做:

    nCount = 0;

    其实是:

    this->nCount = 0;

    基于相同的道理,上例中的EnumObjectdsProc既然是一个成员函数,C++编译器也会为它多准备一个隐藏参数。  

    好,问题就出在这个隐藏参数。callback函数是给Windows调用的,Windows并不借助任何对象调用这个函数,也就没有this指针给callback函数,于是导致堆栈中有一个随机变量会成为指针,而其结果当然是程序的崩溃了。

    要把某个函数用作callback函数,这必须告诉C++编译器,不要让this指针作为该函数的最后一个参数。采用以下两个方法可以做到这一点:

    1.  不要使用类的成员函数(也就是说,要使用全局函数)作为callback函数。

    2.  使用static成员函数。也就是在函数前面加上static修饰词。

    第一种做法相当于在C语言中使用callback函数。第二种做法比较接近OO的精神。

    我想更进一步提醒你的是,C++中的static成员函数特性是,即使对象还没有产生,static成员也已经存在(函数或变量都如此)。换句话说,对象还没有产生之前你已经可以调用类的static函数或使用类的static变量了。请参阅第2章。

    也就是说,凡声明为static的东西(不管函数或变量)都并不和对象结合在一起,它们是类的一部分,不属于对象。

转载地址:http://fxtsi.baihongyu.com/

你可能感兴趣的文章
STM32的两个.bin文件如何合并?
查看>>
合并BIN文件的两种方法
查看>>
网线中哪几根真正有用?
查看>>
STM32的SPI时钟
查看>>
UltraEdit 操作小技巧--一次性修改多列
查看>>
IAR的有用的快捷键
查看>>
FTP工具取消被动模式的办法,cuteftp/flashfxp 被动模式!
查看>>
关于pasv模式中,数据端口由谁指定
查看>>
norflash芯片内执行(XIP)
查看>>
STM32 中断向量表的位置 、重定向
查看>>
STM32 启动解析,启动代码,__main main
查看>>
STM32 keil mdk启动代码发分析
查看>>
stm32 库文件_line 函数
查看>>
深入理解SP、LR和PC
查看>>
stm32应用部分发生中断,PC跳转到IAP中断向量表处后,如何跳转到应用部分中断函数入口的
查看>>
选择ARM7还是cortex-M3?
查看>>
EMC与EMI的区别
查看>>
STM32的串口采用DMA方式接收数据测试
查看>>
STM32的串口采用DMA方式发送数据测试
查看>>
msps
查看>>