首页 > 代码库 > 回调函数的应用误区3(大彻大悟的回调小程序,例子的解释相当给力)

回调函数的应用误区3(大彻大悟的回调小程序,例子的解释相当给力)

研究了一段时间回调函数,越看越迷惑,分析并改进了从网上看到的几篇好文,看过后有了自己的看法。我也不知道这些跌跌撞撞的认识是否符合回调的真实原理,若有大侠能帮解惑,自当感激不尽。

下面的代码可以在Vs2008下编译并运行:

所有的回调函数文章里,能让我一下看明白回调函数的就是这篇文章了,描述简单,一语中的:http://hi.baidu.com/zht7216/item/1dd32e82a68c40d15f0ec154

摘选如下:

  函数指针是一个指向函数的指针变量,它是专门来存放函数入口地址的,在程序中给它赋予哪个函数的入口地址,它就指向哪个函数,因此在一个程序中,一个函数的指针可被多次赋值,指向不同的函数。

#include <stdio.h>

int max(int x , int y);
int min(int x , int y);
int add(int x , int y);
int process(int x , int y , int(*fun)(int , int));

//客户程序C
void main()
{
    int a=10,b=2;
    printf("a=%d, b=%d\n", a, b);
    printf("process(a,b,max)=%d\n", process(a,b,max));//注册回调函数
    printf("process(a,b,min)=%d\n", process(a,b,min));
    printf("process(a,b,add)=%d\n", process(a,b,add));
}

int max(int x , int y)
{
    return x>y?x:y;
}

int min(int x , int y)
{
    return x<y?x:y;
}



int add(int x, int y)
{
    return x + y;
}

//服务程序S

int process(int x, int y, int(* fun)(int, int))
{
    int result;
    result = (*fun)(x , y);
    return result;
}

在这里我见到了对回调函数大彻大悟的解释:

按照刚才的逻辑,其实所声明的三个功能函数:max ,min ,add 就是回调函数。

      请看:

     使用回调函数实际上就是在调用某个函数时将自己的一个函数(这个函数就是回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这是你可以利用这个机会,在回调函数中处理消息或完成一定的操作。

     也可以这样理解:

      所谓回调,就是客户程序C(main)调用服务程序S中的某个函数A(process),然后S又在某个时候反过来调用C中的某个函数B(max),对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。

     一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B叫什么,所以S会约定B的接口规范(函数原 型),然后由C提前通过S的一个函数R(process)告诉S,自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。

       下面举个通俗的例子:
      某天,我打电话向你请教问题,当然是个难题,:),你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这 样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。
这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。

      2. 什么情况下使用回调


      如果你是SDK的使用者,一旦别人制定了回调机制,那么你被迫得使用回调函数,因此这个问题只对SDK设计者有意义。
从引入的目的看,回调大致分为三种:
1) SDK有消息需要通知应用程序,比如定时器被触发;
2) SDK的执行需要应用程序的参与,比如SDK需要你提供一种排序算法;
3) SDK的操作比较费时,但又不能让应用程序阻塞在那里,于是采用异步方式,让调用函数及时返回,SDK另起线程在后台执行操作,待操作完成后再将结果通知应用程序。
经上面这样一总结,你也许会恍然大悟:原来“回调机制”无处不在啊!
是的,不光是Win32 API编程中你会用到,也不光是其它SDK编程中会用到,平时我们自己编写程序时也可能用到回调机制,这时,我们既是回调的设计者又是回调的使用者。