我最近在和一些人谈论我正在编写的程序时听到了“hook”这个词。我不确定这个术语到底意味着什么,尽管我从对话中推断钩子是一种函数类型。我寻找一个定义,但无法找到一个好的答案。有没有人能告诉我这个术语的一般含义,或者举个小例子来说明这个定义?


当前回答

当遇到某些条件时,可以执行钩子。例如,一些变量发生了变化,或者调用了一些动作,或者发生了一些事件。hook可以进入过程并更改内容或对更改作出反应。

其他回答

A chain of hooks is a set of functions in which each function calls the next. What is significant about a chain of hooks is that a programmer can add another function to the chain at run time. One way to do this is to look for a known location where the address of the first function in a chain is kept. You then save the value of that function pointer and overwrite the value at the initial address with the address of the function you wish to insert into the hook chain. The function then gets called, does its business and calls the next function in the chain (unless you decide otherwise). Naturally, there are a number of other ways to create a chain of hooks, from writing directly to memory to using the metaprogramming facilities of languages like Ruby or Python.

钩子链的一个例子是MS Windows应用程序处理消息的方式。处理链中的每个函数要么处理消息,要么将其发送给链中的下一个函数。

在一般意义上,“钩子”是让程序员查看和/或与/或改变系统/程序中已经发生的事情的东西。

例如,Drupal CMS为开发人员提供了钩子,允许他们在创建“内容节点”之后采取额外的操作。如果开发人员没有实现钩子,则按常规创建节点。如果开发人员实现了钩子,他们可以在创建节点时运行一些额外的代码。这段代码可以做任何事情,包括回滚和/或更改原始操作。它还可以做一些与节点创建完全无关的事情。

回调可以被认为是一种特定类型的钩子。通过在系统中实现回调功能,该系统允许您在操作完成后调用一些额外的代码。然而,钩子(作为一个通用术语)并不局限于回调。

另一个例子。有时Web开发人员会将元素上的类名和/或id称为钩子。这是因为通过在元素上放置ID/类名,他们可以使用Javascript修改该元素,或“钩入”到页面文档。(这是一个延伸的意思,但它是常用的,值得一提)

简单的说:

钩子是在现有代码之前、之后或代替现有代码执行自定义代码(函数)的一种方法。例如,为了在继续正常登录过程之前执行验证码函数,可以编写一个函数“hook”到登录过程中。

钩子是软件为用户提供的功能,在特定情况下调用他们自己的代码。该代码可以增加或替换当前代码。

在电脑真正属于个人的时代,病毒还不那么流行(我说的是80年代),它就像打补丁操作系统软件本身来调用你的代码一样简单。我记得我在Apple II上写了一个Applesoft BASIC语言的扩展,它在任何一行被处理之前,通过向我的代码注入一个调用,简单地将我的代码连接到BASIC解释器中。

一些计算机预先设计了钩子,苹果II上的I/O流就是一个例子。它使用这样一个钩子注入整个磁盘子系统(Apple II rom最初是在盒式磁带是个人电脑主要存储介质的年代制造的)。你通过打印ASCII码4 (CTRL-D)来控制磁盘,后面跟着你想要执行的命令,然后是一个CR,它被磁盘子系统拦截,它已经将自己连接到苹果ROM打印例程中。

例如,这几行:

PRINT CHR(4);"CATALOG"
PRINT CHR(4);"IN#6"

会列出磁盘内容,然后重新初始化计算机。这样就可以通过设置第一行来保护你的BASIC程序:

123 REM XIN#6

然后使用POKE在X所在的位置插入CTRL-D字符。然后,任何试图列出源代码的人都会通过磁盘子系统检测到的输出例程发送重新初始化序列。

这通常是我们为了得到我们想要的行为而不得不采取的手段。

现在,由于操作系统更加安全,它为钩子本身提供了便利,因为您不再需要“在运行中”或在磁盘上修改操作系统。

它们已经存在很长时间了。大型机有这些功能(称为出口),甚至现在还有大量的大型机软件使用这些功能。例如,z/OS附带的免费源代码控制系统(称为SCLM)允许您通过在出口中放置自己的代码来完全替换安全子系统。

通常挂钩指的是Win32消息挂钩或Linux/OSX的等等物,但更一般的挂钩只是通知另一个对象/窗口/程序等,当指定的操作发生时,你想被通知。例如:让系统上的所有窗口在即将关闭时通知您。

作为一般规则,钩子有点危险,因为在不了解它如何影响系统的情况下这样做可能会导致不稳定或至少是意想不到的行为。在某些情况下,它也非常有用。例如:FRAPS使用它来确定应该在哪个窗口显示FPS计数器。