No hay "devolución de llamada" en C, no más que cualquier otro concepto de programación genérico.
Se implementan utilizando punteros de función. Aquí hay un ejemplo:
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
for (size_t i=0; i<arraySize; i++)
array[i] = getNextValue();
}
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10, getNextRandomValue);
...
}
Aquí, la populate_array
función toma un puntero de función como su tercer parámetro y lo llama para obtener los valores con los que llenar la matriz. Hemos escrito la devolución de llamada getNextRandomValue
, que devuelve un valor aleatorio, y le hemos pasado un puntero populate_array
. populate_array
llamará a nuestra función de devolución de llamada 10 veces y asignará los valores devueltos a los elementos en la matriz dada.
Aquí hay un ejemplo de devoluciones de llamada en C.
Supongamos que desea escribir un código que permita registrar las devoluciones de llamada cuando se produce algún evento.
Primero defina el tipo de función utilizada para la devolución de llamada:
Ahora, defina una función que se utiliza para registrar una devolución de llamada:
Así es como se vería el código que registra una devolución de llamada:
En lo interno del despachador de eventos, la devolución de llamada puede almacenarse en una estructura que se parece a esto:
Así es como se ve el código que ejecuta una devolución de llamada.
fuente
libsrtp
no da advertencias. Supongo, entonces, que cuando dicho tipo aparece como un argumento de función, se requiere 'decaer' a un puntero a función, al igual que las matrices decaen a los punteros a sus primeros elementos, por lo que sucede lo mismo al final de cualquier manera. Sin embargo, es interesante que las discusiones sobre los tipos de letra que he encontrado no echen un vistazo a este aspecto, sino que se centren en declarar prototipos o punteros con élUn simple programa de devolución de llamada. Espero que responda tu pregunta.
fuente
Una función de devolución de llamada en C es el equivalente de un parámetro / variable de función asignado para ser utilizado dentro de otra función. Ejemplo de Wiki
En el siguiente código,
La función (* numberSource) dentro de la función llamar a PrintTwoNumbers es una función para "devolver la llamada" / ejecutar desde dentro de PrintTwoNumbers según lo dicte el código mientras se ejecuta.
Entonces, si tuviera algo así como una función pthread, podría asignar otra función para que se ejecute dentro del ciclo desde su creación de instancias.
fuente
Una devolución de llamada en C es una función que se proporciona a otra función para "volver a llamar" en algún momento cuando la otra función está haciendo su tarea.
Hay dos formas de utilizar una devolución de llamada : devolución de llamada síncrona y devolución de llamada asíncrona. Se proporciona una devolución de llamada síncrona a otra función que realizará alguna tarea y luego regresará a la persona que llama con la tarea completada. Se proporciona una devolución de llamada asíncrona a otra función que va a iniciar una tarea y luego volver a la persona que llama con la tarea posiblemente no completada.
Una devolución de llamada síncrona se usa generalmente para proporcionar un delegado a otra función a la que la otra función delega algún paso de la tarea. Ejemplos clásicos de esta delegación son las funciones
bsearch()
yqsort()
la Biblioteca estándar de C. Ambas funciones toman una devolución de llamada que se utiliza durante la tarea que proporciona la función, de modo que el tipo de los datos que se buscan, en el caso debsearch()
, u ordenados, en el caso deqsort()
, no necesitan ser conocidos por la función usado.Por ejemplo, aquí hay un pequeño programa de muestra con el
bsearch()
uso de diferentes funciones de comparación, devoluciones de llamada síncronas. Al permitirnos delegar la comparación de datos a una función de devolución de llamada, labsearch()
función nos permite decidir en tiempo de ejecución qué tipo de comparación queremos usar. Esto es sincrónico porque cuando labsearch()
función regresa, la tarea está completa.Una devolución de llamada asincrónica es diferente en que cuando la función llamada a la que proporcionamos una devolución de llamada regresa, la tarea puede no completarse. Este tipo de devolución de llamada a menudo se usa con E / S asíncrona en la que se inicia una operación de E / S y luego, cuando se completa, se invoca la devolución de llamada.
En el siguiente programa, creamos un socket para escuchar las solicitudes de conexión TCP y cuando se recibe una solicitud, la función que realiza la escucha invoca la función de devolución de llamada proporcionada. Esta sencilla aplicación puede ejercerse ejecutándola en una ventana mientras usa la
telnet
utilidad o un navegador web para intentar conectarse en otra ventana.Extraje la mayor parte del código WinSock del ejemplo que Microsoft proporciona con la
accept()
función en https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspxEsta aplicación inicia un
listen()
en el host local, 127.0.0.1, utilizando el puerto 8282 para que pueda utilizartelnet 127.0.0.1 8282
ohttp://127.0.0.1:8282/
.Esta aplicación de muestra se creó como una aplicación de consola con Visual Studio 2017 Community Edition y está utilizando la versión de sockets Microsoft WinSock. Para una aplicación de Linux, las funciones de WinSock necesitarían ser reemplazadas por las alternativas de Linux y la biblioteca de hilos de Windows usaría
pthreads
en su lugar.fuente
Las devoluciones de llamada en C generalmente se implementan utilizando punteros de función y un puntero de datos asociado. Pasa sus
on_event()
punteros de función y datos a una función marcowatch_events()
(por ejemplo). Cuando ocurre un evento, su función se llama con sus datos y algunos datos específicos del evento.Las devoluciones de llamada también se utilizan en la programación de la GUI. El tutorial GTK + tiene una buena sección sobre la teoría de señales y devoluciones de llamada .
fuente
Este artículo de Wikipedia tiene un ejemplo en C.
Un buen ejemplo es que los nuevos módulos escritos para aumentar el servidor web Apache se registran en el proceso principal de apache pasándoles punteros de función para que esas funciones se vuelvan a llamar para procesar las solicitudes de la página web.
fuente
Por lo general, esto se puede hacer usando un puntero de función, que es una variable especial que apunta a la ubicación de memoria de una función. Luego puede usar esto para llamar a la función con argumentos específicos. Por lo tanto, probablemente habrá una función que establezca la función de devolución de llamada. Esto aceptará un puntero de función y luego almacenará esa dirección en algún lugar donde pueda usarse. Después de eso, cuando se activa el evento especificado, llamará a esa función.
fuente
Es mucho más fácil entender una idea a través del ejemplo. Lo que se ha dicho sobre la función de devolución de llamada en C hasta ahora son excelentes respuestas, pero probablemente el mayor beneficio de usar la función es mantener el código limpio y ordenado.
Ejemplo
El siguiente código C implementa la ordenación rápida. La línea más interesante en el código a continuación es esta, donde podemos ver la función de devolución de llamada en acción:
Compare_s2b es el nombre de la función que qsort () está utilizando para llamar a la función. Esto mantiene qsort () tan ordenado (por lo tanto, más fácil de mantener). Simplemente llama a una función por su nombre desde dentro de otra función (por supuesto, la declaración del prototipo de la función, al menos, debe excluirse antes de que pueda llamarse desde otra función).
El código completo
fuente