烟消bug云散的专栏

今天在看相机的调用部分代码时碰见了一个回调函数的问题,开始没注意看,后来才发现是回调函数,不是很懂查了很多资料,整理了一下:

回调函数:调用函数必须是静态成员函数或者全局函数来实现回调函数

所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B叫甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。下面举个通俗的例子:某天,我打电话向你请教问题,当然是个难题,:),你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。

2.什么情况下使用回调如果你是SDK的使用者,一旦别人制定了回调机制,那么你被迫得使用回调函数,因此这个问题只对SDK设计者有意义。从引入的目的看,回调大致分为三种:1) SDK有消息需要通知应用程序,比如定时器被触发;2) SDK3) SDK经上面这样一总结,你也许会恍然大悟:原来“回调机制”无处不在啊!是的,不光是Win32API编程中你会用到,也不光是其它SDK编程中会用到,平时我们自己编写程序时也可能用到回调机制,,这时,我们既是回调的设计者又是回调的使用者。

this用法比较经典的例子:

假设有一个容器类和一个部件类,在容器类的某个方法中要创建部件类的实例对象,而部件类的构造方法要接受一个代表其所在容器的参数。例如:

class Container{

Componentcomp;

publicvoid addComponent(){

}

}

class Component{

ContainermyContainer;

publicComponent(Container c){

myContainer= c;

}

}

光看概念的话不是很懂,但是后来看了一下第二个例子就明白了,回调函数就是在提醒系统某个时候该用到某个函数,跟函数调用不一样,往往类与类之间存在着互相包含的关系。

再看看我遇到的例子:

class GrabImage : public QThread //继承派类(QT多线程重写){public:GrabImage();~GrabImage();bool ConfigureCamera(string &ccfPath);bool ReleaseSource(void);static void XferCallback(SapXferCallbackInfo *pInfo);void GrabStop();void run();public:unsigned char *image;unsigned char *dynamicImage;int frameCnt;int buffWidth, buffHeight;int maxLines;bool isPrepared;static bool useStaticGrab;static int currentCnt;private://property on cameraSapAcquisition *myAcq;SapBuffer *myBuffer;SapTransfer *myTransfer;unsigned char *pImage[2];static int idx;};#endif

然后是类的构成:

bool GrabImage::ConfigureCamera(string &ccfPath){//Free previous resourceReleaseSource();myAcq = new SapAcquisition(SapLocation("Xcelera-CL_LX1_1", 0), ccfPath.c_str());myBuffer = new SapBufferWithTrash(2, myAcq);myTransfer = new SapAcqToBuf(myAcq, myBuffer, XferCallback, this);//注册回调函数

}

SapAcqToBuf(SapAcquisition*pAcq, SapBuffer* pBuf, SapXferCallback pCallback = NULL,void*pContext = NULL);

void GrabImage::XferCallback(SapXferCallbackInfo *pInfo)

{

。。。。

}

可以看到里面调用了GrabImage本身的函数XferCallback所以在这里我们是需要使用回调函数的,而this指的就是我们要使用的这个类本身

另外,附c++静态成员函数,和c++静态成员比较好的解释:点击打开链接

人生就是一次充满未知的旅行,在乎的是沿途的风景,

烟消bug云散的专栏

相关文章:

你感兴趣的文章:

标签云: