在我们的之前的函数调用中,我们通常是通过定义函数,声明函数,然后直接在main函数里面直接使用,这种情况相当于有不管有没有信号来我们都直接响应,那么我们遇到有条件的去响应事件时,我们应该怎么做呢,这时我们就引出了函数的回调:
函数回调的用法三步骤:
[1]定义一个回调函数;
[2]提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
[3]当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
举例如下:
#include<stdio.h>
//具体函数实现 回调函数的实现
//function.c
PTM_INT32 fhdrv_dsp_tune_wave_port(PTM_INT32 unit,PTM_UINT8 port_num, PTM_UINT16 logic_wave_id, PTM_UINT8 set_type);
PTM_INT32 fhdrv_dsp_get_wave_port(PTM_INT32 unit, PTM_UINT8 port_num,PTM_UINT16 *logic_wave_id, PTM_UINT8 *set_type);
PTM_INT32 fhdrv_dsp_get_modulation_format(PTM_INT32 unit, PTM_UINT8 lane_num, ACX00_MODULATION_FORMAT_T *mode_type);
PTM_INT32 fhdrv_dsp_set_modulation_format(PTM_INT32 unit, PTM_UINT8 lane_num, ACX00_MODULATION_FORMAT_T mode_type);
//提供函数注册,可供其他任务选择是否调用,开始默认不使用
//fun.h
typedef struct drv_fun
{
INT32 (* dsp_set_wave_port)(INT32 unit, UINT8 port_num, UINT16 logic_wave_id, UINT8 set_type);
INT32 (* dsp_get_wave_port)(INT32 unit, UINT8 port_num, UINT16 *logic_wave_id, UINT8 *set_type);
INT32 (* dsp_set_modulation_format)(INT32 unit,UINT8 port_num, ACX00_MODULATION_FORMAT_T mode_type);
INT32 (* dsp_get_modulation_format)(INT32 unit,UINT8 port_num, ACX00_MODULATION_FORMAT_T* mode_type);
}DRV_FUN;
extern DRV_FUN g_acxx_drv_func={0};
//reg.c
void reg_fun()
{
g_acxx_drv_func.dsp_set_wave_port = fhdrv_dsp_tune_wave_port;
g_acxx_drv_func.dsp_get_wave_port = fhdrv_dsp_get_wave_port;
g_acxx_drv_func.dsp_set_modulation_format = fhdrv_dsp_set_modulation_format;
g_acxx_drv_func.dsp_get_modulation_format = fhdrv_dsp_get_modulation_format;
}
//在项目初始化的时候选择是否注册函数
void init()
{
reg_fun();
}
//main.c
#include"fun.h"
int main()
{
g_acxx_drv_func.dsp_set_wave_port(..) //此时用函数是NULL
init();
//这样就可以使用回调函数了
//而且注册之后我们也可以不用,这就是函数回调的精妙之处,我们可以有选择的去使用自己的函数
g_acxx_drv_func.dsp_set_wave_port(..);
}
注释:我们先定义一组函数指针,然后将具体的实现函数注册给这定义的函数指针,然后通过是否注册来判断是否调用这一组任务。
补充:函数指针的举例说明:
#include<stdio.h>
#include<string.h>
void check(char* a,char* b,int(*cmp)(const char*,const char*))
{
if(!(*cmp)(a,b))
{
printf("equal\n");
}
else
{
printf("not equal\n");
}
}
int main()
{
char s1[20] = "123";
char s2[20] = "abc";
int(*p)(const char*,const char*);
p = strcmp;
check(s1,s2,p);
return 0;
}
4,现在我们举一个加减乘除的简单实现
(1) fun.h 主要是声明功能实现函数和函数指针的声明:
//fun.h
//函数声明
void plus_fun(int a,int b,int* result);
void muls_fun(int a,int b,int* result);
void mult_fun(int a,int b,int* result);
void except_fun(int a,int b,int* result);
//定义函数指针
typedef struct pointer_fun
{
void (*my_plus)(int a,int b,int* result);
void (*my_muls)(int a,int b,int* result);
void (*my_mult)(int a,int b,int* result);
void (*my_except)(int a,int b,int* result);
}POINTER_FUN;
(2) function.c 函数的具体实现:
void plus_fun(int a,int b,int* result)
{
*result = a + b;
}
void muls_fun(int a,int b,int* result)
{
*result = a - b;
}
void mult_fun(int a,int b,int* result)
{
*result = a * b;
}
void except_fun(int a,int b,int* result)
{
if(b != 0)
{
*result = a / b;
}
}
(3) main.c 只要实现函数指针的调用:
#include<stdio.h>
#include"fun.h"
//全局函数的声明
POINTER_FUN g_pointer_fun = {0};
//函数指针的注册
void reg_fun()
{
g_pointer_fun.my_plus = plus_fun;
g_pointer_fun.my_muls = muls_fun;
g_pointer_fun.my_mult = mult_fun;
g_pointer_fun.my_except = except_fun;
}
int main()
{
reg_fun(); //在需要调用的地方加入注册
int result = 0;
if(g_pointer_fun.my_plus != NULL)
{
g_pointer_fun.my_plus(1,2,&result);
printf("result = %d\n",result);
}
g_pointer_fun.my_muls(6,2,&result);
printf("result = %d\n",result);
g_pointer_fun.my_mult(5,2,&result);
printf("result = %d\n",result);
g_pointer_fun.my_except(12,2,&result);
printf("result = %d\n",result);
return 0;
}
(4)gcc main.c function.c 即可得到结果: