zoukankan      html  css  js  c++  java
  • 回调函数

    定义

    如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(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
    ",(const char *)str);
    }
    
    void count_numbers(void *num)
    {
        int i=0;
        for(i=1;i<=(int)num;i++)
        {
            printf("%d ",i);
        }
        putchar('
    ');
    }
    
    
    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); 则会使用默认函数,程序运行结果为:

  • 相关阅读:
    英雄
    Sublime text 2/3 中 Package Control 的安装与使用方法
    python安装
    flex与C# Socket通信
    ActionScript接收socket服务器发送来的数据
    什么是Socket,为什么要用Socket
    Response.End(); 用HttpContext.Current.ApplicationInstance.CompleteRequest 代替
    探索C#之6.0语法糖剖析
    行为树(Behavior Tree)实践(1)– 基本概念
    浅谈层次化的AI架构
  • 原文地址:https://www.cnblogs.com/doitjust/p/13973075.html
Copyright © 2011-2022 走看看