函数指针和回调函数

来源:互联网 发布:win10 sql sever 编辑:程序博客网 时间:2024/05/17 07:46

C++很多类库都用回调函数,比如MFC中的定时器,消息机制,hook机制等。回调函数与QT中的信号-槽机制很像,但回调更快,而信号-槽更灵活。

1. 回调函数

什么是回调函数呢?回调函数其实就是一个通过函数指针调用的函数!假如你把A函数的指针当作参数传给B函数,然后在B函数中通过A函数传进来的这个指针调用A函数,那么这就是回调机制。A函数就是回调函数,而通常情况下,A函数是系统在符合你设定条件的情况下会自动执行,比如Windows下的消息触发等等。那么调用者和被调用者的关系就被拉开了,就像是中断处理函数那样。

更为通俗的定义理解:

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

2.  函数指针

函数指针是一个指针,只是这个指针它不像普通的指针指向是是一个变量,此时它指向的是一个函数,也就是它存储的是一个函数的地址,如果我们愿意的话,可以改变这个它的值,让他由指向funA转变为指向funB,那么这个函数指针的作用就改变了。

3.  函数指针的使用

函数指针的声明:

typedef 返回类型(*函数指针类型名)(函参列表);
示例:
typedef void(*Fun)(int,int); //定义函数指针类型void min(int a,int b);void max(int a,int b);void min(int a,int b){int minvalue=a<b?a:b;std::cout<<"min value is "<<minvalue<<"\n";}void max(int a,int b){int maxvalue=a>b?a:b;std::cout<<"Max value is "<<maxvalue<<"\n";}int _tmain(int argc, _TCHAR* argv[]){Fun pFun=NULL; //定义函数指针变量pFun//pFun=min;//两种赋值方式都支持pFun=&min;pFun(1,2);//这里获得最小值//pFun=max;pFun=&max;pFun(1,2);//这里获得最大值return 0;}

4.  回调函数的使用

回调函数的使用其实和上面函数指针示例是很一致的,只是上面的实例中pFun是我们自己调用的。现在我们在MFC中让系统调用一下吧。

先看一下SetTimer函数声明:

UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );

其中lpfnTimer是这么解释的:Specifies the address of the application-supplied TimerProc callback function that processes the WM_TIMER messages. If this parameter is NULL, the WM_TIMER messages are placed in the application's message queue and handled by the CWnd object.
也就是或如果为NULL的话,系统自动触发WM_Timer消息,然后调用OnTimer函数。

我们调用自己的自定义回调函数。
CALLBACK VOID callback_fun(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime){TRACE("CallBack\n");//debug下运行控制台输出CallBack}void CTestCallBackDlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码SetTimer(1,1000,(TIMERPROC)callback_fun);//每一秒回调一次}
另外,需要注意的是回调函数必须是全局函数或者静态成员函数,因为普通的成员函数会隐含着一个传递函数作为参数,也就是this指针。因此如果使用普通成员函数作为回调函数的话会导致函数参数个数不匹配,因此编译失败。这也是线程函数是多为静态函数的原因。
我们还注意到回调函数用CALLBACK修饰,我们可以在windef.h中发现:
#define CALLBACK    __stdcall


0 0
原创粉丝点击