C语言 - 钩子函数详解

	自学到线程池  被各种函数指针的套娃操作套蒙了, 所以写一篇来总结一下。

首先要搞清楚几个事情
函数指针和指针函数
函数指针是指针,可以指向任一“同类型”的函数
指针函数是函数,这个函数的返回值是指针 如 int * max(int , int );

钩子函数实际上就是函数指针,首先看下什么是函数指针:

1.函数指针:
函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针
有两个用途:调用函数和做函数的参数。(来自百度百科)

2.函数指针的声明方法
返回值类型 ( * 指针变量名) ([形参列表]);
举例如下图(pFun 应该是function pointer的缩写吧,我看到好多资料都这么命名,所以我照猫画虎)
C语言 - 钩子函数详解_第1张图片
这个时候我们就可以来使用一下

#include 
//函数功能模块   
int max(int a, int b){
    if(a > b)
        return a;
    return b;
}

int min(int a, int b){
    if(a > b)
        return b;
    return a;
}

int main(int argc, char *argv[]){
    //根据上面的功能函数具有的特征来定义一个函数指针 (函数指针就是指向函数的指针!!!!别绕晕了)
    int (*pFun)(int x, int y); 
    
    int a = 1;
    int b = 2;
    int ret;//定义一个变量来接收调用函数后的返回值

    /**
     * 关键  开始挂钩了!!!这就是挂钩操作  
     * 把max函数的地址交给pFun这个指针一份,相当于我把max的入口交给了pFun,这样通过pFun就可以使用max
     **/
    pFun = max;

    ret = pFun(a, b);//相当于直接调用max(a,b);
    printf("%d\n", ret);
    return 0;
}

这个时候我们就会简单的使用钩子函数了, max和min这两个函数就是钩子函数, pFun = max这个操作就叫挂钩子,辛辛苦苦搞懂了这个钩子函数,感觉然并卵,想让钩子函数功能更强大更灵活,就必须介绍下面这步 注册!其实就是把挂钩子这个操作从main函数中拿出来,单独搞了个函数,这个函数的参数就是指向函数的指针(即函数指针)。

注册函数长这样

int RegFun( int (* pFun)(int x, int y) );//这括号里面不就是函数指针吗

上面百度百科也说了钩子函数的作用就两个
1.调用函数(上面的例子已经说明如何调用函数)。
2.作为函数的参数(下面这个注册函数就体现了钩子函数的第二个作用)。

#include 
int (*global_pFun)(int a, int b);//由于后面要在注册函数中进行挂钩操作,所以把这个函数指针定义成全局变量

//括号内的int (*pFun)(int a, int b) 是一个函数指针形参(符合这个指针的函数都可以被作为参数传进来) 
int RegFun(int (*pFun)(int a, int b)){
	global_pFun = pFun;
	return 0;
}

//函数功能
int max(int a, int b){
    if(a > b)
        return a;
    return b;
}
int min(int a, int b){
    if(a > b)
        return b;
    return a;
}
int main(int argc, char **argv){
	int a = 1; 
	int b = 2;
	int ret;
	RegFun(max);//和max挂钩
	ret = global_pFun(a, b);
	printf("%d\n", ret);
	return 0;
}

内心os 写完感觉是在脱裤子放屁一样 传来传去的
下面就是参考文末链接中 大神的例子了 当我们在实际应用中,某一平台要执行某一操作,但这个操作还不确定是什么(没有实际经验的我个人理解应该像是任务系统吧,比如你有新手任务和成长任务还有七日任务,这个时候你就需要这么一个玩意儿(RegFun)来暂时 顶一下 大家都是任务,但是还不确定是哪一类。 如果我说的不对欢迎大家指正我哈,自学渣渣全靠猜测的)

所以实用型的钩子函数诞生了

#include 
int (*g_pFun)(int a, int b);//由于后面要在注册函数中进行挂钩操作,所以把这个函数指针定义成全局变量

//单独看这个函数是完全不知道要对x, y做什么操作的,所以可猜测到main函数里的情况一定是先挂钩(知道自己做什么)再调用plat函数
void plat(){
	int x = 1;
	int y = 2;
	int ret;
	ret = g_pFun(x, y);//这里要和什么功能挂钩我们暂时不知道
	
	printf("%d\n",ret);
}

//这里开始挂钩 括号内的int (*pFun)(int a, int b) 是一个函数指针形参(符合这个指针的函数都可以被作为参数传进来) 
int RegFun(int (*pFun)(int a, int b)){
	g_pFun = pFun;
	return 0;
}

//函数功能
int max(int a, int b){
    if(a > b)
        return a;
    return b;
}
int min(int a, int b){
    if(a > b)
        return b;
    return a;
}

int main(int argc, char **argv){
	RegFun(max);//这里就是执行具体操作的地方咯
	plat();
	
	RegFun(min);
	plat();
	return 0;
}

钩子函数的精妙之处在于我们无法修改平台上的任何数据,只能通过注册函数调用功能模块提供的函数,决定对数据进行什么操作。
推荐参考博客1
推荐参考博客2

你可能感兴趣的:(自学c,c语言,指针)