函數指針的項目中舉例使用(函數回調)

在我們的之前的函數調用中,我們通常是通過定義函數,聲明函數,然後直接在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 即可得到結果:

 

 

 

 

 

 

 

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