回调函数

定义

如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(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); 则会使用默认函数,程序运行结果为:

 

posted @ 2020-11-14 13:59  doitjust  阅读(562)  评论(0编辑  收藏  举报