2011-07-24 27 views
6

Trong sách Learning OpenCV, tôi đã đến hạn callback và đôi khi được sử dụng với routinecallback routine.Gọi lại thường lệ

Ý của chúng tôi là gì khi nói callback?

Cảm ơn.

+1

Gọi lại là cách thanh lịch hơn bình chọn mãi mãi. Nó là một phần của mô hình lập trình hướng sự kiện. –

Trả lời

5

"Tôi không gọi nó một mình, nhưng hệ thống (hoặc một số người khác) sẽ gọi nó". Đó là gọi lại.

13

Chức năng gọi lại là gì?
Trong điều kiện đơn giản, Chức năng gọi lại là chức năng không được người lập trình gọi rõ ràng. Thay vào đó, có một số cơ chế liên tục chờ đợi cho các sự kiện xảy ra, và nó sẽ gọi các chức năng được lựa chọn để đáp ứng với các sự kiện cụ thể.
Cơ chế này thường được sử dụng khi hoạt động (chức năng) mất nhiều thời gian để thực thi và người gọi hàm không muốn đợi cho đến khi thao tác hoàn tất, nhưng muốn được kết quả của thao tác. Thông thường, chức năng Gọi lại giúp triển khai cơ chế không đồng bộ, trong đó người gọi đăng ký để nhận được thông tin về kết quả của quá trình xử lý tốn thời gian và các hoạt động khác liên tục trong thời gian sau đó, người gọi sẽ được thông báo về kết quả.

Một ví dụ thực tế:
của Windows xử lý sự kiện:
hầu như tất cả các chương trình cửa sổ thiết lập một vòng lặp sự kiện, mà làm cho chương trình ứng phó với các sự kiện đặc biệt (ví dụ như nút ép, lựa chọn một hộp kiểm tra, cửa sổ nhận được tập trung) bằng cách gọi một hàm. Điều thuận tiện là lập trình viên có thể chỉ định chức năng nào được gọi khi (nói) một nút cụ thể được nhấn, mặc dù không thể chỉ định khi nào nút sẽ được nhấn. Hàm được gọi được gọi là gọi lại.

Một nguồn tin Mã Minh họa:

//warning: Mind compiled code, intended to illustrate the mechanism  
#include <map> 

typedef void (*Callback)(); 
std::map<int, Callback> callback_map; 

void RegisterCallback(int event, Callback function) 
{ 
    callback_map[event] = function; 
} 

bool finished = false; 

int GetNextEvent() 
{ 
    static int i = 0; 
    ++i; 
    if (i == 5) finished = false; 
} 

void EventProcessor() 
{ 
    int event; 
    while (!finished) 
    { 
     event = GetNextEvent(); 
     std::map<int, Callback>::const_iterator it = callback_map.find(event); 
     if (it != callback_map.end()) // if a callback is registered for event 
     { 
      Callback function = *it; 
      if (function) 
      { 
       (*function)(); 
      } 
      else 
      { 
       std::cout << "No callback found\n"; 
      } 
     } 
    } 
} 

void Cat() 
{ 
    std::cout << "Cat\n"; 
} 

void Dog() 
{ 
    std::cout << "Dog\n"; 
} 

void Bird() 
{ 
    std::cout << "Bird\n"; 
} 

int main() 
{ 
    RegisterCallBack(1, Cat); 
    RegisterCallback(2, Dog); 
    RegisterCallback(3, Cat); 
    RegisterCallback(4, Bird); 
    RegisterCallback(5, Cat); 

    EventProcessor(); 
    return 0; 
} 

Trên đây sẽ ra như sau:

Cat 
Dog 
Cat 
Bird 
Cat 

Hope this helps!


Lưu ý:
nhập câu trả lời này từ một trong những câu trả lời cũ của tôi here.

+0

Con trỏ hàm = xấu. – Puppy

+2

Tôi hiểu 'functors' là tốt nhưng tôi không thấy làm thế nào' function con trỏ' là rất xấu, khi mục đích là để làm cho một hiểu callbacks? –

3

Có nghĩa là bạn chuyển con trỏ đến quy trình đến OpenCV. Đây sẽ là called back khi có điều gì đó xảy ra. Điều này có thể, ví dụ: xem tại cvSetMouseCallback(). Hàm được tham chiếu bởi con trỏ sẽ được gọi bất cứ khi nào con chuột di chuyển.

2

"Thường quy" trong ngữ cảnh này giống với "hàm".Thuật ngữ quay trở lại các ngôn ngữ cũ (như Fortran) tạo ra sự khác biệt giữa các hàm, trả về các giá trị và các thường trình con (phụ) không.

"Gọi lại" là kỹ thuật mà bạn cung cấp con trỏ đến một trong các chức năng của bạn ("thói quen") cho hệ thống/API/khung và hệ thống/API/framework sẽ gọi lại khi cảm thấy như vậy. Vì vậy, một thói quen gọi lại, hoặc đơn giản là gọi lại, là một chức năng dành cho việc sử dụng đó.

Trong ngôn ngữ đối tượng nghiêm ngặt (như Java), họ thường sử dụng người nghe và đại biểu cho điều đó. Kỹ thuật gọi lại, ở dạng C++, có ưu điểm tương thích với các ngôn ngữ không hướng đối tượng như cổ điển C.

EDIT: trong thư viện thời gian chạy Microsoft C, kỹ thuật này được sử dụng cho hàm qsort() . Đối số compare là một con trỏ hàm đến một thường trình gọi lại. Nó được gọi bởi RTL bất cứ khi nào hai phần tử mảng cần được so sánh. Nó không phải là một ví dụ điển hình vì tất cả các cuộc gọi đến compare xảy ra trước khi trả về cuộc gọi qsort().

Trong Win32 API, gọi lại là một yếu. Các thủ tục cửa sổ là một ví dụ chính - bạn vượt qua một con trỏ đến nó trong cấu trúc WNDCLASS, hệ thống gọi thủ tục trở lại khi tin nhắn đến. Trong trường hợp này, thường trình gọi lại được gọi lâu sau RegisterClass() - cho toàn bộ vòng đời của cửa sổ.

Trong POSIX/Unix/Linux, chức năng xử lý tín hiệu là một ví dụ. Xem mô tả syscall tín hiệu().

+0

Cảm ơn bạn đã trả lời tốt đẹp của bạn. Bạn có thể đưa ra một ví dụ về điều đó để làm cho nó rõ ràng hơn? Đặc biệt là khi bạn nói: ** "Callback" là một kỹ thuật mà bạn cung cấp một con trỏ tới một trong các hàm của bạn ("routines") tới hệ thống/API/framework và hệ thống/API/framework sẽ gọi nó trở lại khi nó cảm thấy như vậy. **? Cảm ơn – Simplicity

1

Theo nguyên tắc Holywood "Không gọi cho chúng tôi, chúng tôi gọi cho bạn", một cuộc gọi lại là một tham chiếu đến một hàm được chuyển đến một hàm khác.

Gọi lại sẽ được gọi bằng chức năng được cung cấp cho ví dụ khi dữ liệu có sẵn hoặc cần thực hiện một số bước xử lý nhất định.

0

Chức năng gọi lại là chức năng không được gọi một cách rõ ràng các chức năng tự động được gọi sau khi một số sự kiện xảy ra, ví dụ sau khi nhấn "ctrl + c" SIGINT tín hiệu được tạo ra để xử lý tự động sẽ thực thi.

Các vấn đề liên quan