钩子函数

百度百科

钩子函数是Windows消息处理机制的一部分,通过设置“钩子”,应用程序可以在系统级对所有消息、事件进行过滤,访问在正常情况下无法访问的消息。钩子的本质是一段用以处理系统消息的程序,通过系统调用,把它挂入系统。

WINDOWS的钩子函数可以认为是WINDOWS的主要特性之一。利用它们,您可以捕捉您自己进程或其它进程发生的事件。通过“钩挂”,您可以给WINDOWS一个处理或过滤事件的回调函数,该函数也叫做“钩子函数”,当每次发生您感兴趣的事件时,WINDOWS都将调用该函数。

个人理解

代码执行有一定的流程,比如说第一步做什么,第二步做什么,第三步做什么,每一步对应一个执行函数,这里说的第几步只是说的某些特定阶段,并不一定是连续在一起的。有时候这些函数体可能是空的,什么也没有做,但是是有一个流程在那里的,这种某一步对应的函数就叫钩子函数,并且钩子函数是有一个具体名称的,是系统到了某个阶段检测到有就自动调用,钩子函数里面的代码是有程序员自己编写。并且这个回答是针对所有编程语言说的。

其实和回调是一个概念,当系统执行到某处时,检查是否有hook,有则回调。

钩子函数和回调函数的区别

一般认为,钩子函数就是回调函数的一种,其实还是有差异的,差异地方就是:触发的时机不同。

先说钩子函数:

钩子(Hook)概念源于Windows的消息处理机制,通过设置钩子,应用程序对所有消息事件进行拦截,然后执行钩子函数。

let btn = document.getElementById("btn"); btn.onclick = () => { console.log("i'm a hook"); } 上面的例子,在按钮点击时候立即执行钩子函数。而看下面的例子:

btn.addEventListener("click",() =>{ console.log(this.onclick);//undefined }); 给btn绑定了一个监听器,只有消息捕获完成之后才能触发回调函数。

很明显的差别就是:钩子函数在捕获消息的第一时间就执行,而回调函数是捕获结束时,最后一个被执行的。

回调函数其实是调用者将回调函数的指针传递给了调用函数,当调用函数执行完毕后,通过函数指针来调用回调函数。而钩子函数在消息刚发出,没到达目的窗口前就先捕获了该消息,先得到控制权执行钩子函数,所以他可以加工改变该消息,当然也可以不作为,还可以强行结束该消息。

【完】

对于无知的人,你需要的不是说服他,而是要远离他。

代码理解钩子函数

钩子函数也叫回调函数,是通过函数指针来实现的。

#include "stdio.h"

void fun1(void)
{
    printf("i am fun1\r\n");
}

void fun2(void)
{
    printf("i am fun2\r\n");
}

int main(int argc, char const *argv[])
{
    void (* fun)(void); //定义一个函数指针

    // 让fun指向fun1
    fun = fun1;
    // 执行fun
    fun();

    // 让fun指向fun2
    fun = fun2;
    // 执行fun
    fun();

    return 0;
}

其实说到这,我们已经会用钩子函数了,只是还没引入专业术语而已,在这里,fun1和fun2就是钩子函数,把函数指针fun指向fun1和fun2的过程称为“挂钩子”, 这个很形象吧。其实在这有人会问,为什么我不直接调用fun1和fun2函数,偏偏要通过定义一个函数指针来实现,这不是变得更麻烦,说到这,我只想说有些实物是适合在不同的场合,不是一定得这样用的, 我先说说一个场景。这是因为,我们在写main函数的时候,可能还不知道它会完成什么功能,这时候留下函数指针作为接口,可以挂上不同的函数完成不同的功能,究竟执行什么功能由钩子函数的编写者完成。

那我们平时怎么用的呢?

在我们的代码中,常常把挂钩子的过程叫做注册,会提供一个注册函数,让使用者把自己编写的钩子函数挂在已经声明的函数指针上,这个注册函数的参数就是我们的函数指针了,比如,我们可以给刚才的函数指针提供一个注册函数。

原文链接:https://blog.csdn.net/FourLeafCloverLLLS/article/details/89513701

results matching ""

    No results matching ""