Что подразумевается под термином «крючок» в программировании?

248

Недавно я услышал термин «крючок», когда говорил с некоторыми людьми о программе, которую я писал. Я точно не знаю, что подразумевается под этим термином, хотя из разговора я понял, что ловушка - это тип функции. Я искал определение, но не смог найти хороший ответ. Может ли кто-нибудь дать мне представление о том, что обычно означает этот термин, и, возможно, небольшой пример, иллюстрирующий это определение?

Крис
источник
3
Смотрите Hooking @ Wikipedia . Ссылка скрыта в одном из ответов с более низким голосованием.
Палек

Ответы:

143

По сути, это место в коде, которое позволяет вам подключиться к модулю, чтобы обеспечить другое поведение или реагировать, когда что-то происходит.

Михей
источник
7
Это похоже на обратный вызов?
Крис
19
Хуки часто (но не всегда) используют функции обратного вызова. Например, вы можете подключить систему событий, используя «hookEvent (Events.STARTUP, myCallbackFunction)». Вы передаете указатель на функцию hookEvent, чтобы она знала, какую функцию вызывать при возникновении события. Надеюсь, это поможет :-)
Уильям Брендель
6
именно. Обратный вызов - это «тип» хука.
Мика
21
эм ... нет Обратный вызов является обратным вызовом и не имеет ничего общего с хуками, обратные вызовы просто ИСПОЛЬЗУЮТСЯ для РЕАЛИЗАЦИИ методов хуков. Обратные вызовы - это указатели (RELJMP) на функции / методы / процедуры (CALL), а ловушки - это модификации работающих приложений.
специалист
1
@SahilBabbar Нет. Прерывание вызывает выполнение инструкций в определенном месте (прерывание). Вы можете подключиться к процессу обработки прерываний, например, изменив таблицу, в которой перечислены местоположения обработчиков прерываний, чтобы ваш код вызывался первым по прерыванию (а затем ваш код вызывал бы ранее существующий код обработки прерываний, в в виде цепочки)
Дэвид Тонхофер
77

Хук - это функциональность, предоставляемая программным обеспечением для пользователей этого программного обеспечения, чтобы их собственный код вызывался при определенных обстоятельствах. Этот код может увеличить или заменить текущий код.

В старые времена, когда компьютеры были по-настоящему личными, а вирусы были менее распространенными (я говорю о 80-х), это было так же просто, как исправление самого программного обеспечения операционной системы для вызова вашего кода. Я помню, как писал расширение для языка Applesoft BASIC на Apple II, которое просто подключало мой код к интерпретатору BASIC, вводя вызов в мой код перед обработкой любой строки.

У некоторых компьютеров были заранее спроектированные зацепки, один из которых - поток ввода-вывода на Apple II. Он использовал такую ​​зацепку для внедрения всей дисковой подсистемы (ПЗУ Apple II изначально создавались в те дни, когда кассеты были основным носителем данных для ПК). Вы управляли дисками, печатая код 4 ( CTRL-D) ASCII, а затем команду, которую вы хотели выполнить, затемCR , и она была перехвачена дисковой подсистемой, которая подключилась к процедурам печати Apple ROM.

Так, например, строки:

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

будет перечислять содержимое диска, а затем повторно инициализировать машину. Это позволило использовать такие хитрости, как защита ваших основных программ, установив в первой строке:

123 REM XIN#6

затем использовать POKEдля вставки CTRL-Dсимвола, где Xбыл. Затем любой, кто пытается перечислить ваш источник, отправит последовательность повторной инициализации через выходные процедуры, где дисковая подсистема обнаружит это.

К таким хитростям мы часто прибегали, чтобы добиться желаемого поведения.

В настоящее время операционная система более безопасна и предоставляет возможности для перехвата, поскольку вам больше не нужно изменять операционную систему «в полете» или на диске.

Они были вокруг в течение долгого времени. Они были у мэйнфреймов (так называемые выходы), и многие мэйнфреймы используют их уже сейчас. Например, бесплатная система контроля исходного кода, поставляемая с z / OS (называемая SCLM), позволяет полностью заменить подсистему безопасности, просто разместив свой собственный код на выходе.

paxdiablo
источник
41

В общем смысле «крючок» - это то, что позволит вам, программисту, просматривать и / или взаимодействовать и / или изменять то, что уже происходит в системе / программе.

Например, Drupal CMS предоставляет разработчикам хуки, которые позволяют им предпринимать дополнительные действия после создания «узла содержимого». Если разработчик не реализует ловушку, узел создается в обычном режиме. Если разработчик реализует ловушку, он может запускать дополнительный код всякий раз, когда создается узел. Этот код может делать что угодно, включая откат и / или изменение исходного действия. Это также может сделать что-то не связанное с созданием узла полностью.

Обратный вызов может рассматриваться как особый вид хука. Внедряя функцию обратного вызова в систему, эта система позволяет вам вызывать дополнительный код после завершения действия. Однако перехват (как общий термин) не ограничивается обратными вызовами.

Другой пример. Иногда веб-разработчики будут ссылаться на имена классов и / или идентификаторы элементов как хуки. Это потому, что, помещая имя ID / класса в элемент, они могут затем использовать Javascript для изменения этого элемента или «подключить» к документу страницы. (это растягивает смысл, но это обычно используется и стоит упомянуть)

Алан Сторм
источник
Что вы подразумеваете под «подключиться к странице документа»? Не могли бы вы привести пример? Я понял первый пример - присвоение html-элемента id, чтобы вы могли использовать javacript для изменения элемента.
совершиландройдер
21

Просто сказал:

Хук - это средство выполнения пользовательского кода (функции) до, после или вместо существующего кода. Например, функция может быть написана для «подключения» к процессу входа в систему, чтобы выполнить функцию Captcha перед продолжением обычного процесса входа в систему.

Джозеф Вернис
источник
Лучший ответ IMO
Даниэль
15

Перехват в программировании - это техника, использующая так называемые перехватчики для создания цепочки процедур в качестве обработчика событий.

geowa4
источник
15

Хуки - это категория функций, которая позволяет базовому коду вызывать код расширения. Это может быть полезно в ситуациях, когда основной разработчик хочет предложить расширяемость, не раскрывая свой код.

Одно из применений хуков - в разработке модов для видеоигр. Игра может не позволять разработчикам модов расширять базовую функциональность, но разработчики базовой библиотеки модов могут добавлять хуки. С помощью этих хуков независимые разработчики могут вызывать свой собственный код для вызова любого желаемого события, такого как загрузка игры, обновления инвентаря, взаимодействия с сущностями и т. Д.

Обычный метод реализации - дать функции пустой список обратных вызовов, а затем предоставить возможность расширить список обратных вызовов. Базовый код всегда будет вызывать функцию в одно и то же время, но при пустом списке обратных вызовов функция ничего не делает. Это по замыслу.

Таким образом, третья сторона имеет возможность написать дополнительный код и добавить свой новый обратный вызов в список обратных вызовов ловушки. Имея не что иное, как ссылку на доступные хуки, они обладают расширенной функциональностью с минимальным риском для базовой системы.

Хуки не позволяют разработчикам делать то, что нельзя сделать с другими структурами и интерфейсами. Их выбор следует делать с учетом задачи и пользователей (сторонних разработчиков).

Для пояснения: ловушка позволяет расширение и может быть реализована с использованием обратных вызовов. Обратные вызовы, как правило, не более, чем указатель на функцию; вычисляемый адрес функции. Там, кажется, путаница в других ответах / комментариях.

Джек Стаут
источник
4

Hook обозначает место в коде, где вы отправляете событие определенного типа, и если это событие было зарегистрировано ранее с соответствующей функцией для обратного вызова, то оно будет обработано этой зарегистрированной функцией, иначе ничего не произойдет.

срочный
источник
2

Хуки могут быть выполнены, когда встречаются некоторые условия. например, некоторые переменные изменяются или вызывается какое-то действие, или происходит какое-то событие. крючки могут войти в процесс и изменить вещи или реагировать на изменения.

dusoft
источник
1

Часто перехват относится к перехвату сообщений Win32 или эквивалентам Linux / OSX, но в более общем смысле перехват - это просто уведомление другого объекта / окна / программы / и т. Д., О котором вы хотите получать уведомление, когда происходит указанное действие. Например: наличие всех окон в системе уведомит вас, когда они собираются закрыться.

Как правило, перехватывать несколько опасно, так как выполнение этого без понимания того, как это влияет на систему, может привести к нестабильности или, как минимум, к неожиданному поведению. Это также может быть ОЧЕНЬ полезно в определенных обстоятельствах, подумал. Например: FRAPS использует его, чтобы определить, в каких окнах должен отображаться счетчик FPS.

Тодзи
источник
1

Цепочка хуков - это набор функций, в которых каждая функция вызывает следующую. Что важно в цепочке хуков, так это то, что программист может добавить еще одну функцию в цепочку во время выполнения. Один из способов сделать это - найти известное место, где хранится адрес первой функции в цепочке. Затем вы сохраняете значение этого указателя на функцию и перезаписываете значение по начальному адресу на адрес функции, которую вы хотите вставить в цепочку подключений. Затем вызывается функция, выполняет свою работу и вызывает следующую функцию в цепочке (если вы не решите иначе). Естественно, есть ряд других способов создать цепочку хуков, от прямой записи в память до использования средств метапрограммирования таких языков, как Ruby или Python.

Пример цепочки хуков - способ, которым приложение MS Windows обрабатывает сообщения. Каждая функция в цепочке обработки либо обрабатывает сообщение, либо отправляет его следующей функции в цепочке.

Джо Приносящий Душу
источник
1

В системе управления контентом Drupal «крючок» имеет относительно специфическое значение. Когда происходит внутреннее событие (например, создание контента или логин пользователя), модули могут реагировать на это событие, реализуя специальную функцию «ловушки». Это делается с помощью соглашения об именах - например, [your-plugin-name] _user_login () для события User Login.

Из-за этого соглашения лежащие в основе события упоминаются как «ловушки» и появляются с именами, такими как «hook_user_login» и «hook_user_authenticate ()» в документации API Drupal.

Eaton
источник
Это следует за упомянутой выше идеей «обратного вызова» «реагировать, когда что-то происходит». В этом случае обратный вызов не регистрируется явно, а основан на «магическом именовании». В настоящее время это обсуждается на drupal.org, см. Использование Symfony EventDispatcher для перехватов событий
donquixote
В целом, ловушка / обратный вызов / слушатель может быть «сделана известной вызывающему коду» различными способами (не говоря, что это завершено): 1. магически названные функции 2. магически названные классы 3. явно зарегистрированные функции 4. явно зарегистрированные объекты (слушатели, подписчики, наблюдатели) 5. явно зарегистрированные имена классов (+ необязательные аргументы конструктора), которые должны быть созданы до срабатывания ловушки. 6. изменив код вызова
donquixote
1

Короче говоря, вы можете изменить код вызова API, например, MessageBoxгде он выполняет другую функцию, отредактированную вами (глобально будет работать во всей системе, локально будет работать во всем процессе).

Кенни Баркер
источник