编程中术语“钩子”是什么意思?

我最近在和一些人谈论我正在写的一个节目的时候听到了“钩子”这个词。 我不确定这个术语究竟意味着什么,尽pipe我从对话中推断出钩子是一种function。 我search了一个定义,但无法find一个好的答案。 有人能够给我一个这个术语通常意义的概念,也许是一个小例子来说明这个定义吗?

从本质上讲,它是一个代码的地方,允许你使用一个模块来提供不同的行为,或者在事情发生时做出反应。

挂钩是由软件为用户提供的function,在某些情况下可以调用自己的代码。 该代码可以增加或replace当前的代码。

在过去的时代,电脑真的是个人电脑,病毒不太stream行(我正在谈论80年代),就像修补操作系统软件本身来调用你的代码一样简单。 我记得在Apple II上写了一个Applesoft BASIC语言的扩展,通过在处理任何行之前向我的代码注入一个调用,就可以将我的代码挂接到BASIC解释器中。

一些电脑有预先devise的钩子,一个例子就是Apple II上的I / Ostream。 它使用这样一个钩子来注入整个磁盘子系统(Apple II ROM最初是在盒式磁带作为PC的主要存储介质的时候build立的)。 您通过打印 ASCII代码4( CTRL-D ),然后执行您想要执行的命令然后CR来控制磁盘,磁盘子系统将其截取到Apple ROM打印例程中。

所以例如,行:

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

会列出磁盘内容,然后重新初始化机器。 这可以通过设置第一行为保护您的BASIC程序这样的技巧:

 123 REM XIN#6 

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

这往往是我们不得不采取的欺骗手段,以获得我们想要的行为。

现在,在操作系统更安全的情况下,它提供了钩子本身的function,因为你不再需要修改操作系统“在飞行中”或在磁盘上。

他们已经在很长一段时间了。 大型机有他们(称为出口),大量的主机软件甚至现在使用这些设施。 例如,z / OS随附的免费源代码控制系统(称为SCLM)允许您通过简单地将自己的代码放在出口中来完全replace安全子系统。

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

例如,Drupal CMS为开发者提供了一些钩子,让他们在创build“内容节点”之后采取额外的行动。 如果一个开发者没有实现一个钩子,那么该节点是按照正常的方式创build的 如果一个开发人员实现一个钩子,每当创build一个节点时,他们可以运行一些额外的代码。 这个代码可以做任何事情,包括回滚和/或改变原来的行为。 它也可以完成一些与节点创build无关的事情。

callback可以被认为是一种特定的钩子。 通过在系统中实现callback函数,该系统让你在一个动作完成之后调用一些额外的代码。 但是,钩子(作为通用术语)不限于callback。

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

挂钩编程是一种使用所谓的钩子来作为事件处理程序来创build一系列程序的技术。

钩子是允许基本代码调用扩展代码的一类function。 这在核心开发人员希望在不暴露代码的情况下提供可扩展性的情况下非常有用。

钩子的一个用法是在video游戏mod开发中。 一个游戏可能不允许mod开发人员扩展基本function,但钩子可以由核心mod库开发人员添加。 借助这些钩子,独立开发人员可以根据任何期望的事件调用自定义代码,例如游戏加载,库存更新,实体交互等。

一个常见的实现方法是给函数一个空的callback列表,然后展示扩展callback列表的能力。 基本代码将始终在相同和适当的时间调用该函数,但是,使用空的callback列表,该函数什么也不做。 这是devise。

第三方则有机会编写额外的代码,并将新的callback添加到钩子的callback列表中。 除了可用钩子的参考外,它们扩展了基本系统风险最小的function。

钩子不允许开发人员做任何其他结构和接口无法做到的事情。 他们是考虑到任务和用户(第三方开发者)的select。

澄清:一个钩子允许扩展,可以使用callback实现。 callback通常只不过是一个函数指针; 计算出的函数地址。 其他回答/评论似乎有些混乱。

Hook表示在你调度某个types事件的代码中的一个地方,如果这个事件之前被注册了一个合适的函数来callback,那么它将被这个注册函数处理,否则什么都不会发生。

简单的说:

钩子是在现有代码之前,之后或代替现有代码执行自定义代码(函数)的手段。 例如,为了在继续进行正常的login过程之前执行validation码function,可以将函数写入“挂接”到login过程中。

当遇到一些情况时,可以执行钩子。 例如某些variables或某些动作被调用或某些事件发生。 钩子可以进入过程中,改变事物或在变化时作出反应。

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

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

在Drupal内容pipe理系统中,“钩子”有一个比较具体的含义。 当发生内部事件(例如内容创build或用户login)时,模块可以通过实现特殊的“挂钩”function来响应事件。 例如,通过用户login事件的命名约定 – [your-plugin-name] _user_login()完成。

由于这个约定,底层事件被称为“钩子”,并在Drupal的API文档中以“hook_user_login”和“hook_user_authenticate()”的名字出现。

钩子链是一组函数,其中每个函数调用下一个函数。 钩子链的重要性在于程序员可以在运行时向链中添加另一个函数。 一种方法是寻找一个已知的位置,在这个位置,链中第一个函数的地址被保留。 然后保存该函数指针的值,并使用要插入到钩子链中的函数的地址覆盖初始地址处的值。 该函数然后被调用,执行其业务并调用链中的下一个函数(除非您另有决定)。 当然,还有很多其他方法可以创build一系列钩子,从直接写入内存到使用Ruby或Python等语言的元编程function。

一个钩子链的例子是MS Windows应用程序处理消息的方式。 处理链中的每个函数都会处理一条消息或将其发送到链中的下一个函数。

在很短的时间内,您可以将诸如MessageBox之类的API调用的代码更改为由您编辑的不同function(全局将在系统范围内工作,本地将在全程范围内工作)。