何为CallBack

来源:互联网 发布:宋仲基朴槿惠事件知乎 编辑:程序博客网 时间:2024/04/30 09:13

回调用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条件下触发回调,例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通信中很普遍。

回调和API非常接近,他们的共性都是跨层调用的函数。但区别是API是低层提供给高层的调用,一般这个函数对高层都是已知的;而回调正好相反,他是高层提供给底层的调用,对于低层他是未知的,必须由高层进行安装,这个安装函数其实就是一个低层提供的API,安装后低层不知道这个回调的名字,但它通过一个函数指针来保存这个回调,在需要调用时,只需引用这个函数指针和相关的参数指针。回调就是该函数写在高层,低层通过一个函数指针保存这个函数,在某个事件的触发下,低层通过该函数指针调用高层那个函数。

一:声明回调函数类型。

typedef int (WINAPI*PFCALLBACK)(intParam1,intParam2); 实际上是声明了一个返回值为int,传入参数为两个int的指向函数的指针。由于C++和PASCAL编译器对参数入栈和函数返回的处理有可能不一致,把函数类型用WINAPI(WINAPI宏展开就是__stdcall)或stdcall统一修饰。


二:声明回调函数原形
int WINAPICBFunc(intParam1,intParam2);
以上函数为全局函数,如果要使用一个类里的函数作为回调函数原形,把该类函数声明为静态函数即可。
回调函数就相当于一个中断处理函数,由系统在符合你设定的条件时自动调用。为此,你需要做三件事:1,声明;2,定义;3,设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于系统调用。声明和定义时应注意:回调函数由系统调用,所以可以认为它属于WINDOWS系统。不要把它当作你的某个类的成员函数。
C++编译器为类成员函数多准备了一个隐藏参数(在程序代码中看不到),这个隐藏参数就是this指针,类成员函数靠着this指针才得以抓到正确对象的数据。内存中只会有一份类成员函数,但却可能有许多份类成员变量——每个对象拥有一份。这使得函数类型与Windows callback函数的默认类型不符。问题就出现在这个隐藏参数,  callback函数是给windows调用的,windows并不经由任何对象呼叫这个函数,也就无需传递this指针给callback函数,于是导致堆栈中有一个随机变量会成为this指针,而其结果当然是程序的崩溃了。

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

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

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

第一种做法相当于在C语言中使用callback函数,第二种做法接近OO精神.进一步而言,C++中的static函数特性是,即使对象还没有产生,static成员已经存在(函数或参数都如此).换句话说,物件产生之前你已经可以呼叫类的static函数或者使用类的static变量了;也就是说凡是宣告为static的东西,(不管函数或变量)都并不和对象结合在一起,它们是类的一部分,不属于对象。

原创粉丝点击