web-dev-qa-db-ja.com

プログラミングにおける「フック」という用語の意味は何ですか?

私は最近、私が書いていたプログラムについて何人かの人々と話しているときに「フック」という用語を聞いた。会話から、フックは一種の関数であると推測しましたが、この用語が何を意味するのか正確にはわかりません。定義を検索しましたが、良い答えが見つかりませんでした。誰かがこの用語が一般的に何を意味するのか、おそらく定義を説明するための小さな例のアイデアを私に与えることができますか?

226
Chris

基本的には、モジュールにアクセスして、異なる動作を提供したり、何かが起こったときに反応したりできるようにするコード内の場所です。

132
Micah

フックとは、特定の状況下で独自のコードを呼び出すために、ソフトウェアのユーザーがソフトウェアによって提供される機能です。そのコードは、現在のコードを拡張または置換できます。

コンピューターが本当にパーソナルでウイルスがあまり流行していなかった(私は80年代を話している)昔は、オペレーティングシステムソフトウェア自体にパッチをあててコードを呼び出すだけでした。 Apple IIでApplesoft BASIC言語の拡張機能を作成したことを覚えています。この拡張機能は、行が処理される前にコードに呼び出しを挿入することで、BASICインタープリターにコードをフックしました。

一部のコンピューターには、Apple IIのI/Oストリームなど、事前に設計されたフックがありました。このようなフックを使用して、ディスクサブシステム全体を挿入しました(Apple II ROMは元々、カセットがPCの主要な記憶媒体であった時代に構築されました)。 printing the ASCII code 4(CTRL-D)の後に実行したいコマンドが続き、その後CRでディスクを制御し、インターセプトされましたApple ROM印刷ルーチンにフックしていたディスクサブシステムによって。

たとえば、次の行:

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

ディスクの内容をリストし、マシンを再初期化します。これにより、最初の行を次のように設定して、BASICプログラムを保護するなどのトリックが可能になりました。

123 REM XIN#6

POKEを使用して、Xがあった場所にCTRL-D文字を挿入します。次に、ソースをリストしようとすると、ディスクサブシステムがそれを検出する出力ルーチンを介して再初期化シーケンスが送信されます。

それは、私たちが望んだ行動を得るために頼らざるを得なかった一種の策略です。

最近では、オペレーティングシステムがより安全になり、オペレーティングシステムを「実行中」またはディスク上で変更する必要がなくなったため、フック自体の機能が提供されます。

彼らはlongの時間を過ごしてきました。メインフレームにはそれらがあり(出口と呼ばれます)、現在でも多くのメインフレームソフトウェアがこれらの機能を使用しています。たとえば、z/OSに付属する無料のソースコード管理システム(SCLMと呼ばれる)を使用すると、出口に独自のコードを配置するだけで、セキュリティサブシステムを完全に置き換えることができます。

75
paxdiablo

一般的な意味では、「フック」とは、プログラマーが、システム/プログラムで既に行われているものを表示および/または対話および/または変更できるようにするものです。

たとえば、Drupal CMSは、「コンテンツノード」の作成後に追加のアクションを実行できるフックを開発者に提供します。開発者がフックを実装しない場合、ノードは通常どおりに作成されます。開発者がフックを実装する場合、ノードが作成されるたびに追加のコードを実行させることができます。このコードは、元のアクションのロールバックや変更など、何でもできます。また、ノードの作成とはまったく関係のないこともできます。

コールバックは、特定の種類のフックと考えることができます。システムにコールバック機能を実装することにより、そのシステムはアクションの完了後に追加のコードを呼び出すことができます。ただし、(一般的な用語としての)フックはコールバックに限定されません。

もう一つの例。 Web開発者は、要素のクラス名やIDをフックと呼ぶことがあります。これは、要素にID /クラス名を配置することにより、Javascriptを使用してその要素を変更したり、ページドキュメントに「フック」したりできるためです。 (これは意味を拡張していますが、一般的に使用されており、言及する価値があります)

38
Alan Storm

フックは、基本コードが拡張コードを呼び出すことを可能にする関数のカテゴリです。これは、コア開発者がコードを公開せずに拡張性を提供したい場合に役立ちます。

フックの使用法の1つは、ビデオゲームのmod開発です。ゲームではmod開発者が基本機能を拡張できない場合がありますが、コアmodライブラリ開発者がフックを追加できます。これらのフックを使用すると、独立した開発者は、ゲームの読み込み、インベントリの更新、エンティティの対話などの任意のイベントでカスタムコードを呼び出すことができます。

実装の一般的な方法は、関数にコールバックの空のリストを提供し、コールバックのリストを拡張する機能を公開することです。基本コードは常に同じ適切な時間に関数を呼び出しますが、コールバックリストが空の場合、関数は何もしません。これは仕様です。

サードパーティは、追加のコードを記述し、新しいコールバックをフックのコールバックリストに追加する機会があります。利用可能なフックの参照に過ぎないため、基本システムへのリスクを最小限に抑えながら機能を拡張しています。

フックを使用すると、開発者は他の構造やインターフェイスでは実行できないことを実行できません。これらは、タスクとユーザー(サードパーティの開発者)を考慮して選択する必要があります。

明確化のために:フックは拡張を許可し、コールバックを使用して実装できます。通常、コールバックは関数ポインタにすぎません。関数の計算されたアドレス。他の回答/コメントには混乱があるようです。

15
Jack Stout

フック プログラミングでは、いわゆるフックを使用して、イベントハンドラとしてプロシージャのチェーンを作成する手法です。

14
geowa4

シンプルは言った:

フックは、既存のコードの前、後、または代わりにカスタムコード(関数)を実行する手段です。たとえば、通常のログインプロセスに進む前にCaptcha関数を実行するために、ログインプロセスに「フック」する関数を作成できます。

12
Joseph Vernice

フックは、特定のタイプのイベントをディスパッチするコード内の場所を示します。このイベントがコールバックする適切な関数で以前に登録されていた場合、この登録された関数によって処理されます。

4
urgent

フックは、何らかの条件が発生したときに実行できます。例えば変数の変更、アクションの呼び出し、イベントの発生などがあります。フックはプロセスに入り、物事を変更したり、変更に反応したりできます。

2
dusoft

多くの場合、フックとは Win32メッセージフック または同等のLinux/OSXを指しますが、より一般的なフックは、指定されたアクションが発生したときに通知することを別のオブジェクト/ウィンドウ/プログラム/などに単に通知することです。たとえば、システム上のすべてのウィンドウが閉じようとしているときに通知します。

原則として、システムへの影響を理解せずにフックを行うと、不安定になったり、予期しない動作が発生したりする可能性があるため、フックはやや危険です。また、特定の状況では非常に役立つことも考えられます。たとえば、 FRAPS は、FPSカウンターを表示するウィンドウを決定するために使用します。

1
Toji

フックのチェーンは、各関数が次を呼び出す一連の関数です。フックチェーンの重要な点は、プログラマが実行時に別の関数をチェーンに追加できることです。これを行う1つの方法は、チェーン内の最初の関数のアドレスが保持されている既知の場所を探すことです。次に、その関数ポインターの値を保存し、初期アドレスの値を、フックチェーンに挿入する関数のアドレスで上書きします。次に、関数が呼び出され、そのビジネスを行い、チェーン内の次の関数を呼び出します(他に決定しない限り)。当然、メモリへの直接書き込みからRubyやPythonなどの言語のメタプログラミング機能の使用に至るまで、フックのチェーンを作成する他の多くの方法があります。

フックチェーンの例は、MS Windowsアプリケーションがメッセージを処理する方法です。処理チェーン内の各関数は、メッセージを処理するか、チェーン内の次の関数に送信します。

1

Drupalコンテンツ管理システムでは、「フック」には比較的具体的な意味があります。内部イベント(コンテンツの作成やユーザーのログインなど)が発生すると、モジュールは特別な「フック」機能を実装することでイベントに応答できます。これは、命名規則を介して行われます-たとえば、ユーザーログインイベントの場合は[your-plugin-name] _user_login()です。

この規則により、基礎となるイベントは「フック」と呼ばれ、DrupalのAPIドキュメントでは「hook_user_login」や「hook_user_authenticate()」などの名前で表示されます。

1
Eaton

非常に簡単に言えば、MessageBoxなどのAPI呼び出しのコードを、編集した別の機能を実行する場所に変更できます(グローバルはシステム全体で機能し、ローカルはプロセス全体で機能します)。

1
Kenny Barker