函数指针的项目中举例使用(函数回调)

在我们的之前的函数调用中,我们通常是通过定义函数,声明函数,然后直接在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 即可得到结果:

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章