Có nghĩa là gì bởi thuật ngữ hook hook trong lập trình?


248

Gần đây tôi đã nghe cụm từ "hook" trong khi nói chuyện với một số người về một chương trình tôi đang viết. Tôi không chắc chính xác thuật ngữ này ngụ ý gì mặc dù tôi đã suy luận từ cuộc trò chuyện rằng hook là một loại chức năng. Tôi đã tìm kiếm một định nghĩa nhưng không thể tìm thấy một câu trả lời tốt. Ai đó có thể cho tôi một ý tưởng về thuật ngữ này thường có nghĩa là gì và có lẽ là một ví dụ nhỏ để minh họa cho định nghĩa?


3
Xem Hooking @ Wikipedia . Liên kết được chôn trong một trong những câu trả lời thấp hơn.
Palec

Câu trả lời:


143

Về cơ bản, đây là một vị trí trong mã cho phép bạn chạm vào một mô-đun để cung cấp hành vi khác nhau hoặc phản ứng khi có điều gì đó xảy ra.


7
Điều này có giống với một cuộc gọi lại?
Chris

19
Móc thường (nhưng không phải luôn luôn) sử dụng chức năng gọi lại. Ví dụ: bạn có thể kết nối một hệ thống sự kiện bằng cách sử dụng "hookEvent (Events.STARTUP, myCallbackFunction)". Bạn đang chuyển một con trỏ hàm đến hàm hookEvent, vì vậy nó biết hàm nào sẽ gọi khi sự kiện xảy ra. Hy vọng điều đó sẽ giúp :-)
William Brendel

6
chính xác. Một cuộc gọi lại là một "loại" của hook.
Mi-chê

21
À, không. Một cuộc gọi lại là một cuộc gọi lại và không có gì để làm với các hook, các cuộc gọi lại được sử dụng đơn giản cho việc THỰC HIỆN các phương thức hook. Gọi lại là con trỏ (RELJMP) cho các chức năng / phương thức / thủ tục (CALL), hook là sửa đổi để chạy các ứng dụng.
đặc biệt

1
@SahilBabbar Số Một ngắt làm cho các lệnh tại một nơi được chỉ định (ngắt) được thực thi. Tuy nhiên, bạn có thể nối vào quy trình xử lý ngắt, ví dụ bằng cách sửa đổi bảng liệt kê các vị trí của các trình xử lý ngắt để mã của bạn được gọi trước khi ngắt (và sau đó mã của bạn sẽ gọi mã xử lý ngắt hiện tại trước đó, trong một kiểu cúc dây chuyền)
David Tonhofer

77

Một hook là chức năng được cung cấp bởi phần mềm để người dùng phần mềm đó có mã riêng được gọi trong các trường hợp nhất định. Mã đó có thể tăng hoặc thay thế mã hiện tại.

Vào thời xa xưa khi máy tính thực sự là cá nhân và virus ít phổ biến hơn (tôi đang nói đến thập niên 80), việc đơn giản là tự vá phần mềm hệ điều hành để gọi mã của bạn. Tôi nhớ đã viết một phần mở rộng cho ngôn ngữ Applesoft BASIC trên Apple II, đơn giản là nối mã của tôi vào trình thông dịch BASIC bằng cách thực hiện cuộc gọi đến mã của tôi trước khi bất kỳ dòng nào được xử lý.

Một số máy tính có các móc được thiết kế sẵn, một ví dụ là luồng I / O trên Apple II. Nó đã sử dụng một cái móc như vậy để tiêm toàn bộ hệ thống phụ đĩa (ROM Apple II ban đầu được chế tạo vào thời mà băng cassette là phương tiện lưu trữ chính cho PC). Bạn đã kiểm soát các đĩa bằng cách in mã ASCII 4 ( CTRL-D) theo lệnh bạn muốn thực thi sau đó a CRvà nó đã bị hệ thống phụ đĩa chặn lại, nó đã tự móc vào các thói quen in ROM của Apple.

Vì vậy, ví dụ, các dòng:

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

sẽ liệt kê nội dung đĩa sau đó khởi tạo lại máy. Điều này cho phép các thủ thuật như bảo vệ các chương trình BASIC của bạn bằng cách đặt dòng đầu tiên là:

123 REM XIN#6

sau đó sử dụng POKEđể chèn CTRL-Dký tự vào vị trí X. Sau đó, bất cứ ai cố gắng liệt kê nguồn của bạn sẽ gửi chuỗi khởi tạo lại thông qua các thói quen đầu ra nơi hệ thống phụ đĩa sẽ phát hiện ra nó.

Đó thường là loại mánh khóe mà chúng tôi phải dùng đến, để có được hành vi mà chúng tôi muốn.

Ngày nay, với hệ điều hành an toàn hơn, nó cung cấp các phương tiện cho chính hook, vì bạn không còn phải sửa đổi hệ điều hành "trên máy bay" hoặc trên đĩa.

Họ đã tồn tại trong một thời gian dài . Máy tính lớn có chúng (được gọi là lối thoát) và rất nhiều phần mềm máy tính lớn sử dụng các cơ sở đó ngay cả bây giờ. Ví dụ: hệ thống kiểm soát mã nguồn miễn phí đi kèm với z / OS (được gọi là SCLM) cho phép bạn thay thế hoàn toàn hệ thống con bảo mật bằng cách chỉ cần đặt mã của riêng bạn vào lối ra.


41

Theo một nghĩa chung, "cái móc" là thứ sẽ cho phép bạn, một lập trình viên, xem và / hoặc tương tác và / hoặc thay đổi một cái gì đó đã xảy ra trong một hệ thống / chương trình.

Ví dụ, Drupal CMS cung cấp cho các nhà phát triển các hook cho phép họ thực hiện hành động bổ sung sau khi "nút nội dung" được tạo. Nếu nhà phát triển không thực hiện hook, nút được tạo bình thường. Nếu một nhà phát triển thực hiện một hook, họ có thể có một số mã bổ sung chạy bất cứ khi nào một nút được tạo. Mã này có thể làm bất cứ điều gì, bao gồm quay ngược lại và / hoặc thay đổi hành động ban đầu. Nó cũng có thể làm một cái gì đó không liên quan đến việc tạo nút hoàn toàn.

Một cuộc gọi lại có thể được coi là một loại móc cụ thể. Bằng cách triển khai chức năng gọi lại vào một hệ thống, hệ thống đó cho phép bạn gọi một số mã bổ sung sau khi một hành động đã hoàn thành. Tuy nhiên, hooking (như một thuật ngữ chung) không giới hạn đối với các cuộc gọi lại.

Một vi dụ khac. Đôi khi, Nhà phát triển Web sẽ gọi tên lớp và / hoặc ID trên các thành phần dưới dạng móc. Đó là bởi vì bằng cách đặt ID / tên lớp trên một thành phần, sau đó họ có thể sử dụng Javascript để sửa đổi thành phần đó hoặc "nối vào" tài liệu trang. (điều này đang kéo dài ý ​​nghĩa, nhưng nó thường được sử dụng và đáng nói đến)


Bạn có ý nghĩa gì khi "móc vào tài liệu trang"? Bạn có thể cho một ví dụ? Tôi đã hiểu ví dụ đầu tiên - cung cấp cho phần tử html một id để bạn có thể sử dụng javacript để sửa đổi phần tử.
committedandroider

21

Nói đơn giản:

Một hook là một phương tiện để thực thi mã tùy chỉnh (hàm) trước, sau hoặc thay vì mã hiện có. Ví dụ, một chức năng có thể được ghi vào "hook" vào quy trình đăng nhập để thực thi chức năng Captcha trước khi tiếp tục quá trình đăng nhập thông thường.


Câu trả lời hay nhất
Daniel

15

Hooking trong lập trình là một kỹ thuật sử dụng cái gọi là hook để tạo ra một chuỗi các thủ tục như một bộ xử lý sự kiện.


15

Móc là một loại chức năng cho phép mã cơ sở gọi mã mở rộng. Điều này có thể hữu ích trong các tình huống mà nhà phát triển cốt lõi muốn cung cấp khả năng mở rộng mà không để lộ mã của họ.

Một cách sử dụng hook là trong phát triển mod trò chơi video. Một trò chơi có thể không cho phép các nhà phát triển mod mở rộng chức năng cơ bản, nhưng các hook có thể được thêm bởi các nhà phát triển thư viện mod lõi. Với các hook này, các nhà phát triển độc lập có thể có mã tùy chỉnh của họ được gọi theo bất kỳ sự kiện mong muốn nào, chẳng hạn như tải trò chơi, cập nhật hàng tồn kho, tương tác thực thể, v.v.

Một phương pháp thực hiện phổ biến là cung cấp cho hàm một danh sách các cuộc gọi lại trống, sau đó cho thấy khả năng mở rộng danh sách các cuộc gọi lại. Mã cơ sở sẽ luôn gọi hàm cùng một lúc và đúng thời gian, nhưng với danh sách gọi lại trống, hàm không làm gì cả. Đây là do thiết kế.

Sau đó, một bên thứ ba có cơ hội viết mã bổ sung và thêm cuộc gọi lại mới của họ vào danh sách gọi lại của hook. Không có gì khác hơn là một tài liệu tham khảo về các móc có sẵn, chúng có chức năng mở rộng có nguy cơ tối thiểu đối với hệ thống cơ sở.

Móc không cho phép nhà phát triển làm bất cứ điều gì không thể thực hiện với các cấu trúc và giao diện khác. Chúng là một lựa chọn được đưa ra khi xem xét nhiệm vụ và người dùng (nhà phát triển bên thứ ba).

Để làm rõ: một hook cho phép mở rộng và có thể được thực hiện bằng cách sử dụng các cuộc gọi lại. Các cuộc gọi lại thường không có gì nhiều hơn một con trỏ hàm; địa chỉ tính toán của hàm. Dường như có sự nhầm lẫn trong các câu trả lời / ý kiến ​​khác.


4

Hook biểu thị một vị trí trong mã nơi bạn gửi một sự kiện thuộc loại nhất định và nếu sự kiện này đã được đăng ký trước đó với một chức năng phù hợp để gọi lại, thì nó sẽ được xử lý bởi chức năng đã đăng ký này, nếu không sẽ không có gì xảy ra.


2

móc có thể được thực hiện khi gặp một số điều kiện. ví dụ: một số thay đổi biến hoặc một số hành động được gọi hoặc một số sự kiện xảy ra. móc có thể nhập vào trong quá trình và thay đổi mọi thứ hoặc phản ứng khi thay đổi.


1

Thông thường hooking đề cập đến hook tin nhắn Win32 hoặc tương đương Linux / OSX, nhưng hooking thông thường hơn chỉ đơn giản là thông báo cho một đối tượng / cửa sổ / chương trình / vv khác mà bạn muốn được thông báo khi có hành động được chỉ định. Ví dụ: Có tất cả các cửa sổ trên hệ thống thông báo cho bạn khi chúng sắp đóng.

Theo nguyên tắc chung, hooking có phần nguy hiểm vì thực hiện nó mà không hiểu làm thế nào nó ảnh hưởng đến hệ thống có thể dẫn đến sự mất ổn định hoặc tại các hành vi rất bất ngờ. Nó cũng có thể RẤT hữu ích trong một số trường hợp, suy nghĩ. Ví dụ: FRAPS sử dụng nó để xác định cửa sổ nào sẽ hiển thị trên bộ đếm FPS.


1

Một chuỗi các hook là một tập hợp các hàm trong đó mỗi hàm gọi hàm tiếp theo. Điều có ý nghĩa về một chuỗi các hook là một lập trình viên có thể thêm một chức năng khác vào chuỗi trong thời gian chạy. Một cách để làm điều này là tìm kiếm một vị trí đã biết nơi lưu giữ địa chỉ của hàm đầu tiên trong chuỗi. Sau đó, bạn lưu giá trị của con trỏ hàm đó và ghi đè giá trị tại địa chỉ ban đầu bằng địa chỉ của hàm bạn muốn chèn vào chuỗi hook. Hàm sau đó được gọi, thực hiện công việc của nó và gọi hàm tiếp theo trong chuỗi (trừ khi bạn quyết định khác). Đương nhiên, có một số cách khác để tạo ra một chuỗi các móc nối, từ viết trực tiếp đến bộ nhớ đến sử dụng các phương tiện siêu lập trình của các ngôn ngữ như Ruby hoặc Python.

Một ví dụ về chuỗi các hook là cách ứng dụng MS Windows xử lý các thông báo. Mỗi chức năng trong chuỗi xử lý hoặc xử lý một thông báo hoặc gửi nó đến chức năng tiếp theo trong chuỗi.


1

Trong hệ thống quản lý nội dung Drupal, 'hook' có ý nghĩa tương đối cụ thể. Khi một sự kiện nội bộ xảy ra (ví dụ như tạo nội dung hoặc đăng nhập người dùng), các mô-đun có thể phản hồi sự kiện bằng cách thực hiện chức năng "hook" đặc biệt. Điều này được thực hiện thông qua quy ước đặt tên - ví dụ [tên của bạn-plugin] _user_login () cho sự kiện Đăng nhập người dùng.

Do quy ước này, các sự kiện cơ bản được gọi là "hook" và xuất hiện với các tên như "hook_user_login" và "hook_user_authenticate ()" trong tài liệu API của Drupal.


Điều này tuân theo ý tưởng được đề cập ở trên , về một "cuộc gọi lại" "để phản ứng khi có điều gì đó xảy ra". Trong trường hợp này, cuộc gọi lại không được đăng ký rõ ràng, mà dựa trên "cách đặt tên ma thuật". Điều này hiện đang được thảo luận trên drupal.org, xem Sử dụng Symfony EventDispatcher cho móc sự kiện
donquixote

Để khái quát hóa, một hook / callback / listener có thể được "biết đến mã gọi" theo nhiều cách khác nhau (không nói điều này là hoàn chỉnh): 1. các hàm có tên ma thuật 2. các lớp có tên ma thuật 3. các hàm được đăng ký rõ ràng 4. rõ ràng các đối tượng đã đăng ký (người nghe, người đăng ký, người quan sát) 5. tên lớp được đăng ký rõ ràng (+ hàm tạo tùy chọn lập luận), sẽ được khởi tạo trước khi hook hook. 6. bằng cách sửa đổi mã cuộc gọi
donquixote

1

Nói ngắn gọn, bạn có thể thay đổi mã của lệnh gọi API, chẳng hạn như MessageBoxnơi nó thực hiện một chức năng khác do bạn chỉnh sửa (trên toàn cầu sẽ hoạt động trên toàn hệ thống, cục bộ sẽ hoạt động theo quy trình rộng).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.