注册函数和回调函数使用讲解

1.概念

注册和回调函数在C语言编程中非常常见,也经常用到。注册和回调的机制也大量使用在Linux内核中。学会使用注册和回调函数是C语言开发者应当掌握的一项编程技能。

函数的本质在内存上体现的是地址。我们知道函数的地址后,就能够调用这个函数。
在这里插入图片描述

这里面涉及到两个函数:注册函数A, 回调函数B

所谓注册的过程,就是把一个 指向某个函数B的指针作为参数传递给 注册函数A。注册函数A使用变量(一般是全局变量)把 指向函数B的指针给保存下来。
回调函数,即当因某个事件触发时,通过函数指针调用被保存的函数。

2. 示例

我们来看一个例子来理解注册和回调函数。

2. 1 无参数无返回值的回调函数

#include <stdio.h>  
  
// 定义一个回调函数类型, 无参数无返回值  
typedef void (*CallbackFunction)();  
  
// 声明一个全局变量来存储注册的回调函数  
CallbackFunction g_Callback = NULL;  
  
// 注册回调函数的函数  
void registerCallback(CallbackFunction callback) {  
    g_Callback = callback;  
}  
  
// 模拟的事件触发函数,它会调用注册的回调函数  
void triggerEvent() {  
    if (g_Callback != NULL) {  
        g_Callback();  
    } else {  
        printf("No callback function registered!\n");  
    }  
}  
  
// 用户定义的回调函数1  
void userCallbackFunction1() {  
    printf("User callback function1 called!\n");  
}  

// 用户定义的回调函数2  
void userCallbackFunction2() {  
    printf("User callback function2 called!\n");  
}  
  
int main() {  
    // 注册用户定义的回调函数1  
    registerCallback(userCallbackFunction1);  
  
    // 触发事件,这将调用注册的回调函数1  
    triggerEvent();  

    // 注册用户定义的回调函数2  
    registerCallback(userCallbackFunction2);  
  
    // 触发事件,这将调用注册的回调函数2  
    triggerEvent();
	
    // 取消注册(可选)  
    registerCallback(NULL);  
  
    return 0;  
}

2. 2 有参数无返回值的回调函数

下面的回调函数,带有一个int参数

#include <stdio.h>  
  
// 定义一个回调函数类型, 有参数无返回值  
typedef void (*CallbackFunction)(int num);  
  
// 声明一个全局变量来存储注册的回调函数  
CallbackFunction g_Callback = NULL;  
  
// 注册回调函数的函数  
void registerCallback(CallbackFunction callback) {  
    g_Callback = callback;  
}  
  
// 模拟的事件触发函数,它会调用注册的回调函数  
void triggerEvent() { 
	printf("Please enter a number.\n");
    if (g_Callback != NULL) {
		int num;
		scanf("%d",&num);
        g_Callback(num);  
    } else {  
        printf("No callback function registered!\n");  
    }  
}  
  
// 用户定义的回调函数1  
void userCallbackFunction1(int num) {  
    printf("User callback function1 called!\n");
	printf("num= %d!\n",num);  
}  

// 用户定义的回调函数2  
void userCallbackFunction2(int num) {  
    printf("User callback function2 called!\n"); 
	printf("num= %d\n",num); 	
}  
  
int main() {  
    // 注册用户定义的回调函数1  
    registerCallback(userCallbackFunction1);  
  
    // 触发事件,这将调用注册的回调函数1  
    triggerEvent();  

    // 注册用户定义的回调函数2  
    registerCallback(userCallbackFunction2);  
  
    // 触发事件,这将调用注册的回调函数2  
    triggerEvent();
	
    // 取消注册(可选)  
    registerCallback(NULL);  
  
    return 0;  
}

2. 3 有参数有返回值的回调函数

返回值int, 参数int

#include <stdio.h>  
  
// 定义一个回调函数类型, 有参数有返回值  
typedef int (*CallbackFunction)(int num);  
  
// 声明一个全局变量来存储注册的回调函数  
CallbackFunction g_Callback = NULL;  
  
// 注册回调函数的函数  
void registerCallback(CallbackFunction callback) {  
    g_Callback = callback;  
}  
  
// 模拟的事件触发函数,它会调用注册的回调函数  
void triggerEvent() { 
	printf("Please enter a number.\n");
    if (g_Callback != NULL) {
		int num;
		scanf("%d",&num);
        int result = g_Callback(num);  
		printf("result= %d!\n",result);  
    } else {  
        printf("No callback function registered!\n");  
    }  
}  
  
// 用户定义的回调函数1  
int userCallbackFunction1(int num) {  
    printf("User callback function1 called!\n");
	return num; 
}  

// 用户定义的回调函数2  
int userCallbackFunction2(int num) {  
    printf("User callback function2 called!\n"); 
	return num;	
}  
  
int main() {  
    // 注册用户定义的回调函数1  
    registerCallback(userCallbackFunction1);  
  
    // 触发事件,这将调用注册的回调函数1  
    triggerEvent();  

    // 注册用户定义的回调函数2  
    registerCallback(userCallbackFunction2);  
  
    // 触发事件,这将调用注册的回调函数2  
    triggerEvent();
	
    // 取消注册(可选)  
    registerCallback(NULL);  
  
    return 0;  
}

相信,通过上面的例子,大家已经掌握了注册和回调函数的使用了吧

3.注册和回调的好处

下面我们探讨下,使用注册和回调函数的好处。

1.可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。
在这里插入图片描述
在系统设计中,分层模型。常规的逻辑是,上层调用下层的方法。比如,一个驱动程序,对下屏蔽了硬件细节,对上提供了调用接口。但也会存在下层调用上层方法的情况,这时如果直接调用调用的话,会使得下层的软件特定于一个上层的软件,降低复用性。

使用回调的话,就相对灵活了。调用者不需要关心具体的实现细节,只需要知道存在一个具有特定原型的函数即可。‌ 这种机制使得代码更加模块化和可维护,避免了直接调用带来的灵活性问题‌。

  1. 在程序执行期间可以动态更改被调用的回调函数。

  2. 比直接调用,显得逼格高!

欢迎大家留言评论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

同志啊为人民服务!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值