回调例行程序

Call back routine

本文关键字:程序 回调      更新时间:2023-10-16

Learning OpenCV书中,我提到了callback,有时与routine一起称为callback routine

我们说的callback是什么意思?

谢谢。

什么是Callback函数?
简单来说,回调函数是程序员不显式调用的函数。相反,有一些机制可以持续等待事件的发生,并且它将调用选定的函数来响应特定的事件。当一个操作(函数)需要很长时间才能执行,而函数的调用者不想等到操作完成,但确实希望知道操作的结果时,通常使用这种机制。通常,回调函数帮助实现这样的异步机制,其中调用方注册以获得有关耗时处理和连续其他操作的结果的动画,而在稍后的时间点,调用方获得结果的通知。

一个实际的例子:
Windows事件处理:
实际上所有的Windows程序都设置了一个事件循环,这使得程序通过调用函数来响应特定的事件(例如按钮按下,选择一个复选框,窗口获得焦点)。方便的事情是,程序员可以指定当(比如说)按下特定按钮时调用什么函数,即使不可能指定何时按下按钮。被调用的函数被称为回调函数。

源代码说明:

//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 foundn";
            }
        }
    }
}
void Cat()
{
   std::cout << "Catn";
}
void Dog()
{
    std::cout << "Dogn";
}
void Bird()
{
    std::cout << "Birdn";
}
int main()
{
    RegisterCallBack(1, Cat);
    RegisterCallback(2, Dog);
    RegisterCallback(3, Cat);
    RegisterCallback(4, Bird);
    RegisterCallback(5, Cat);
    EventProcessor(); 
    return 0;
}

上面的命令将输出如下内容:

Cat  
Dog   
Cat  
Bird  
Cat  

希望这对你有帮助!


注意:
从我的一个旧答案中导入这个答案

"我自己不调用它,但系统(或其他一些人)会调用它"。这是

它们意味着您将指向过程的指针传递给OpenCV。当事情发生时,这将是called back。这可以在cvSetMouseCallback()中看到。当鼠标移动时,指针所引用的函数将被调用。

遵循好莱坞的原则"不要呼叫我们,我们呼叫你",回调是对传递给另一个函数的函数的引用。

当数据可用或需要执行某些处理步骤时,回调函数将调用它。

此处的"Routine"与"function"相同。这个术语可以追溯到较早的语言(如Fortran),它们在返回值的函数和不返回值的(子)例程之间做出了区别。

"回调"是一种技术,当你向系统/API/框架提供一个指向你的函数("例程")的指针时,系统/API/框架会在它想这样做的时候回调它。因此,回调例程,或简称回调,就是用于这种用途的函数。

在严格的对象语言(如Java)中,它们通常使用侦听器和委托。c++形式的回调技术有一个优点,那就是它与非面向对象的语言(如经典C语言)兼容。

EDIT:在Microsoft C运行时库中,这种技术用于qsort()函数。compare参数是指向回调例程的函数指针。每当两个数组元素需要比较时,RTL就会调用它。这不是一个典型的例子,因为所有对compare的调用都发生在qsort()调用返回之前。

在Win32 API中,回调是主要的。窗口过程就是一个典型的例子——你在WNDCLASS结构中传递一个指向它的指针,当消息到达时,系统会回调这个过程。在这种情况下,回调例程在RegisterClass()之后很久才被调用——在窗口的整个生命周期中。

在POSIX/Unix/Linux中,以信号处理函数为例。参见signal()系统调用描述

回调函数是不显式调用的函数,此类函数在某些事件发生后自动调用,例如按下"ctrl+c"后产生SIGINT信号,因此自动处理程序将执行