2011-07-24 8 views
6

En el libro Learning OpenCV, llegué al término callback, y algunas veces lo uso con routine como callback routine.Devolver la llamada de rutina

¿Qué queremos decir cuando decimos callback?

Gracias.

+1

La devolución de llamada es una forma más elegante que la votación para siempre. Es parte del modelo de programación impulsado por eventos. –

Respuesta

5

"No lo llamo solo, pero el sistema (u otros) lo llamará". Eso es callback.

13

¿Qué es una función de devolución de llamada?
En términos simples, una función de devolución de llamada es una función que no es llamada explícitamente por el programador. En cambio, hay algún mecanismo que espera continuamente que ocurran eventos, y llamará funciones seleccionadas en respuesta a eventos particulares.
Este mecanismo se utiliza normalmente cuando una operación (función) tarda mucho tiempo en ejecutarse y el llamante de la función no desea esperar hasta que la operación se complete, pero desea ser informado del resultado de la operación. Normalmente, las funciones de devolución de llamada ayudan a implementar un mecanismo asincrónico, en el que el llamante se registra para obtener una estimación del resultado del proceso lento y otras operaciones continuas, mientras que en un momento posterior, la persona que llama se informa del resultado.

Un ejemplo práctico:
procesamiento de eventos de Windows:
prácticamente todos los programas de Windows creados un bucle de eventos, que hace que el programa responde a eventos particulares (por ejemplo pulsaciones de botón, la selección de una casilla de verificación, consiguiendo ventana enfoque) llamando a una función. Lo útil es que el programador puede especificar qué función se llama cuando (por ejemplo) se presiona un botón en particular, aunque no es posible especificar cuándo se presionará el botón. La función que se llama se conoce como devolución de llamada.

Una ilustración de código fuente:

//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; 
} 

Lo anterior sería la siguiente salida:

Cat 
Dog 
Cat 
Bird 
Cat 

Espero que esto ayude!


Nota:
importado esta respuesta de una de mis viejas respuestas here.

+0

Punteros de función = malo. – Puppy

+2

Entiendo que los "funtores" son buenos, pero no veo cómo los "indicadores de función" son tan malos, ¿cuando el propósito es hacer que uno entienda las devoluciones de llamada? –

3

Significan que pasa un puntero a un procedimiento a OpenCV. Esto será called back cuando pase algo. Esto puede, p. visto en cvSetMouseCallback(). La función a la que hace referencia el puntero se llamará cada vez que se mueva el mouse.

2

"Rutina" en este contexto es lo mismo que "función".El término se remonta a los idiomas más antiguos (como Fortran) que hicieron una diferencia entre las funciones, que devuelve valores y (sub) rutinas que no lo hacen.

"Devolución de llamada" es una técnica en la que proporciona un puntero a una de sus funciones ("rutinas") al sistema/API/framework y el sistema/API/framework lo llamará cuando lo desee. Entonces, una rutina de devolución de llamada, o simplemente una devolución de llamada, es una función destinada para dicho uso.

En los lenguajes estrictamente objeto (como Java) suelen utilizar oyentes y delegados para eso. La técnica de devolución de llamada, en su forma C++, tiene la ventaja de que es compatible con lenguajes no orientados a objetos como el clásico C.

EDITAR: en la biblioteca Microsoft C en tiempo de ejecución, esta técnica se utiliza para la función qsort() . El argumento compare es un puntero a la función de una rutina de devolución de llamada. Es llamado por el RTL cada vez que se necesitan comparar dos elementos de la matriz. No es un ejemplo típico porque todas las llamadas a compare suceden antes de que la llamada qsort() regrese.

En Win32 API, las devoluciones de llamadas son un elemento básico. El procedimiento de ventana es un excelente ejemplo: le pasa un puntero en la estructura WNDCLASS, el sistema vuelve a llamar el procedimiento cuando llega el mensaje. En este caso, la rutina de devolución de llamada se invoca mucho después de RegisterClass() - durante toda la vida útil de la ventana.

En POSIX/Unix/Linux, la función de procesamiento de señal es un ejemplo. Ver la descripción de syscall signal().

+0

Gracias por su agradable respuesta. ¿Puedes dar un ejemplo sobre eso para hacerlo más claro? Especialmente cuando dice: ** "Devolución de llamada" es una técnica en la que proporciona un puntero a una de sus funciones ("rutinas") para el sistema/API/marco y el sistema/API/marco lo devolverá cuando tiene ganas de hacerlo. **? Gracias – Simplicity

1

Siguiendo el principio de Holywood "No nos llames, te llamamos", una devolución de llamada es una referencia a una función que se pasa a otra función.

La función a la que se llama llamará a la devolución de llamada, por ejemplo, cuando haya datos disponibles o se necesiten realizar ciertos pasos de procesamiento.

0

Las funciones de devolución de llamada son funciones que no se llaman explícitamente, tales funciones se invocan automáticamente después de que ocurra algún evento, por ejemplo después de presionar "ctrl + c" señal SIGINT generada para que se ejecute automáticamente el manejador.

Cuestiones relacionadas