回调函数
定义
如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(Callback Function)。
示例
回调函数示例:void func( void (*f)(void *) , void *p);
调用者 | 实现者 |
1. 提供一个回调函数,再提供一个准备传给回调函数的参数。 2. 把回调函数传给参数f,把准备传给回调函数的参数按 void * 类型传给参数p |
1. 在适当的时候根据调用这传来的函数指针f调用回调函数, 将调用者传来的参数p转交给回调函数,即调用f(p); |
例子1
实现一个repeat_three_time函数,可以把调用者传来的任何回调函数连续执行三次。
/* para_callback.h */ #ifndef __PARA_CALLBACK_H #define __PARA_CALLBACK_H typedef void (*callback_t)(void *); void repeat_three_times(callback_t f,void *para); #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\r\n",(const char *)str); } void count_numbers(void *num) { int i=0; 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; }
程序运行结果:
例子2
回调函数一般定义在数据结构中,是一个函数指针。通过调用回调函数,客户可以自行编写函数。
OpenSSL中大量用到了回调函数,通过回调函数,客户可以自行编写函数,让OpenSSL函数来调用它,即用户调用OpenSSL提供的含函数,OpenSSL函数再调用用户提供的函数。这样方便了用户对OpenSSL函数操作的控制。
在OpenSSL实现函数中,它一般会实现一个默认的函数来进行处理,如果用户不设置回调函数,则采用它默认的函数。
/* random.h */ #ifndef __RANDOM_H #define __RANDOM_H typedef int *callback_random(char *random,int len); void set_callback(callback_random *cb); int genrate_random(char *random,int len); #endif
/* random.c */ #include "random.h" #include <string.h> callback_random *cb_rand = NULL; static int default_random(char *random,int len) { memset(random,0x01,len); return 0; } void set_callback(callback_random *cb) { cb_rand = cb; } int genrate_random(char *random,int len) { if(cb_rand == NULL) { return default_random(random,len); }else { return cb_rand(random,len); } return 0; }
/* main.c */ #include <stdio.h> #include <string.h> #include "random.h" static int my_rand(char *rand,int len) { memset(rand,0x02,len); return 0; } int main(int argc, char *argv[]) { int i = 0; char random[20]={0}; int ret = 0; set_callback(my_rand); ret = genrate_random(random,10); for(i=0;i<10;i++) { printf("%02X ",random[i]); } return 0; }
程序运行结果:
如果main.c中不调用 set_callback(my_rand); 则会使用默认函数,程序运行结果为: