Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3521576
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类:

2012-10-14 17:11:28

原文地址:C/C++回调函数 作者:apple_guet

精妙比喻:回调函数就像您随身带的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
#include
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    {
        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)的括号不能省略,因为括号的优先级高于星号,那样就成了一个返回类型为整型的函数声明了

阅读(300) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~