回调函数详解

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

 

posted @ 2017-03-21 14:14  大海中的一粒沙  阅读(2565)  评论(0)    收藏  举报