回调函数详解
1. 什么是回调函数?
简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
通俗的将,所谓回调,就是模块A要通过模块B的某个函数b()完成一定的功能,但是函数b()自己无法实现全部功能,需要反过头来调用模块A中的某个函数a()来完成,这个a()就是回调函数。如下图

2. 如何使用回调函数
在使用回调函数时应按以下步骤执行:
①约定接口规范。在模块B必须约定接口规范,也就是定义回调函数a()的函数原型--->即声明回调函数的类型(函数指针类型)
这里回调函数原型的定义最好遵循typedef void (*SCT_XXX)(LPVOID lp, const CBParamStruct& cbNode); SCT_XXX是回调函数名称(定义了一个函数指针类型,名称为SCT_XXX),lp是回调上下文,CBParamStruct是回调参数,一般由于要回调的参数不止一个,所以定义一个结构体比较方便。
②回调函数的注册。为了让模块B知道自己将要使用的回调函数,必须有一个函数或语句来注册回调函数
注册回调函数的定义遵循void RCF_XXX(SCT_XXX pfn, LPVOID lp); RCF_XXX是注册函数名,pfn是回调函数名称(是指针),lp是回调上下文。一般在A模块初始化完B模块后调用,将A模块中定义的回调函数地址赋值给pfn,lp赋值为this。
③在模块A中要做的事情:
首先将回调函数声明成静态的,static void CF_XXX(LPVOID lp, const CBParamStruct& cbNode); 函数的参数必须与B模块中回调函数原型的参数保持一致。
初始化B模块时,调用注册函数将模块A中声明的回调函数CF_XXX的地址传给pfn,即pfn=CF_XXX;(函数名称CF_XXX其实是个指针,指向回调函数的地址) 。
3. 举例
以下是一个简单的例子。实现了一个repeat_three_times函数,可以把调用者传来的任何回调函数连续执行三次。
回调函数
/* para_callback.h */
#ifndef PARA_CALLBACK_H
#define PARA_CALLBACK_H
typedef void (*callback_t)(void *); //约定接口规范,声明了回调函数的类型(类型名称为callback_t,该类型是一个带void*的参数,返回值类型为void)
extern void repeat_three_times(callback_t, void *); //回调函数的注册,
#endif
/* para_callback.c */
#include "para_callback.h"
void repeat_three_times(callback_t f, void *para) //回调函数的注册定义
{
f(para);
f(para);
f(para);
}
/* main.c */
#include <stdio.h>
#include "para_callback.h"
void say_hello(void *str) //具体的回调函数
{
printf("Hello %s\n", (const char *)str);
}
void count_numbers(void *num) //具体的回调函数
{
int i;
for(i=1; i<=(int)num; i++)
printf("%d ", i);
putchar('\n');
}
int main(void)
{
repeat_three_times(say_hello, "Guys");
repeat_three_times(count_numbers, (void *)4);
return 0;
}
本例中回调函数的参数按什么类型解释由调用者规定,对于实现者来说就是一个void *指针,实现者只负责将这个指针转交给回调函数,而不关心它到底指向什么数据类型。
调用者知道自己传的参数是char *型的,那么在自己提供的回调函数中就应该知道参数要转换成char *型来解释。
参考文章:http://www.cnblogs.com/ioleon13/archive/2010/03/02/1676621.html
http://wenku.baidu.com/link?url=TL34FZNH-lX-Kpsk-c18NDfWBJeCpO5Ac1gardHGRu4MnBX7Tw9QhYi8DMSu6nLWJiPh3pAacZTXK0jJgnL4pBC_OdpfY3AaBn3blLaVjAu
http://blog.csdn.net/callmeback/article/details/4242260/
http://blog.sina.com.cn/s/blog_9474609d01017cwb.html
浙公网安备 33010602011771号