C/C++回调函数

C/C++回调函数

回调函数就像您随身带的BP机:告诉别人号码,在它有事情时Call您
    
    回调用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条件下触发回调,例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通信中很普遍。
    
    其实回调和API非常接近,他们的共性都是跨层调用的函数。但区别是API是低层提供给高层的调用,一般这个函数对高层都是已知的;而回调正好相反,他是高层提供给低层的调用,对于低层他是未知的,必须由高层进行安装,这个安装函数其实就是一个低层提供的API,安装后低层不知道这个回调的名字,但它通过一个函数指针来保存这个回调,在需要调用时,只需引用这个函数指针和相关的参数指针。
    
    其实:回调就是该函数写在高层,低层通过一个函数指针保存这个函数,在某个事件的触发下,低层通过该函数指针调用高层那个函数。回调在C语言中是通过函数指针来实现的,通过将回调函数的地址传给被调函数从而实现回调。因此,要实现回调,必须首先定义函数指针,请看下面的例子:
    
    void Func(char *s);// 函数原型     
    void (*pFunc) (char *);//函数指针     
    可以看出,函数的定义和函数指针的定义非常类似。     
    一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。     
    typedef void(*pcb)(char *);     
    回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。     
    被调函数的例子:     
    例一:
    
    void GetCallBack(pcb callback)     
    {     
    /*do something*/     
    }
    
    用户在调用上面的函数时,需要自己实现一个pcb类型的回调函数:     
    void fCallback(char *s)     
    {     
    /* do something */     
    }
    
    然后,就可以直接把fCallback当作一个变量传递给GetCallBack,     
    GetCallBack(fCallback);     
    如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。
    
    例二:    
   
//Test.c    
    #include <stdlib.h>    
    #include <stdio.h>    
    int Test1()    
    {    
	int i;    
    	for (i=0; i<30; i++)    
    	{    
    		printf(“The %d th charactor is: %c\n”, i, (char)(‘a' + i%26));    
    	}    
    	return 0;    
    }
    
    int Test2(int num)    
    {    
    	int i;    
    	for (i=0; i<num; i++)    
    	{    
    		printf(“The %d th charactor is: %c\n”, i, (char)('a' + i%26));    
   	}    
    	return 0;    
    }
    
    void Caller1(void (*ptr)()) //指向函数的指针作函数参数    
    {
       (*ptr)();    
    }
    
    void Caller2(int n, int (*ptr)()) //指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的,    
    {                                     //不能写成void Caller2(int (*ptr)(int n)),这样的定义语法错误。    
    	(*ptr)(n);    
    	return;    
    }
    
    int main()    
    {    
    	printf(“************************\n”);    
  	Caller1(Test1); //相当于调用Test2();    
    	printf(“&&&&&&************************\n”);    
    	Caller2(30, Test2); //相当于调用Test2(30);    
    	return 0;    
    }


    以上通过将回调函数的地址传给调用者从而实现调用,但是需要注意的是带参回调函数的用法。要实现回调,必须首先定义函数指针。函数指针的定义这里稍微提一下。比如:     
    int (*ptr)(); 这里ptr是一个函数指针,其中(*ptr)的括号不能省略,因为括号的优先级高于星号,那样就成了一个返回类型为整型的函数声明了


C++回调函数

回调函数就好像是一个中断处理函数,系统在符合你设定的条件时自动调用。为此,你需要做三件事:

1.  声明;

2.  定义;

3.  设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于系统调用。


申明就是申明一个函数指针;

定义就是实现回调函数;

触发条件就是讲你定义的函数赋值给一个回调函数的指针,调用时,就用这个指针带上函数的参数调用;


1)普通的回调函数

       (1 )函数指针
       
回调在C语言中是通过函数指针来实现的,通过将回调函数的地址传给被调函数从而实现回调。因此,要实现回调,必须首先定义函数指针,请看下面的例子:

      void Func(char *s)//函数原型
       void (*pFunc) (char *);//
函数指针

      可以看出,函数的定义和函数指针的定义非常类似。

      一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。

      typedef void(*pcb)(char *);

      回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。

      被调函数的例子:

      void GetCallBack(pcb callback)
       {
       /*do something*/
       }
       
用户在调用上面的函数时,需要自己实现一个pcb类型的回调函数:
       void fCallback(char *s) 
       {
       /* do something */
       } 
       
然后,就可以直接把fCallback当作一个变量传递给GetCallBack,
       GetCallBack
fCallback;

      如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。



2)回调函数作为函数的参数使用

这种方法在封装SDK时很普遍的用到,比如海康和大华的SDK;

比如海康的DVR 预览SDK:

NET_DVR_API LONG __stdcall NET_DVR_RealPlay_V30(LONG lUserID, LPNET_DVR_CLIENTINFO lpClientInfo, void(CALLBACK *fRealDataCallBack_V30) (LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void* pUser) = NULL, void* pUser = NULL, BOOL bBlocked = FALSE);


NET_DVR_CLIENTINFO ClientInfo;
ClientInfo.hPlayWnd     = GetDlgItem(IDC_STATIC_PLAY)->m_hWnd;
ClientInfo.lChannel     = m_struDeviceInfo.struChanInfo[m_iCurChanIndex].iChanIndex;
ClientInfo.lLinkMode    = 0;
    ClientInfo.sMultiCastIP = NULL;
TRACE("Channel number:%d\n",ClientInfo.lChannel);
m_lPlayHandle = NET_DVR_RealPlay_V30(m_struDeviceInfo.lLoginID,&ClientInfo,NULL,NULL,TRUE);


3)如果回调函数不用做函数的参数,也可以通过一个Init函数,将回调函数传递给类的成员变量,然后在类里面就可以用成员变量进行回调。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值