Implementando funciones de devolución de llamada en C

CBeginner
Practicar Ahora

Introducción

En este proyecto, aprenderás cómo implementar una función de devolución de llamada en el lenguaje C. Las funciones de devolución de llamada son una técnica poderosa en la programación en C, especialmente en el contexto del desarrollo del sistema Linux, donde se utilizan comúnmente.

👀 Vista previa

$ gcc test_callback.c callback.c -o test_callback
$./test_callback
Alarm1:0
Alarm2:1
Alarm3:2

🎯 Tareas

En este proyecto, aprenderás:

  • Cómo definir y utilizar funciones de devolución de llamada en C
  • Cómo registrar y desencadenar alarmas utilizando una función de devolución de llamada
  • Cómo manejar casos extremos y errores en la implementación de la función de devolución de llamada

🏆 Logros

Después de completar este proyecto, serás capaz de:

  • Comprender el concepto de funciones de devolución de llamada y su uso en la programación en C
  • Implementar un sistema de alarma basado en devolución de llamada, incluyendo el registro y el desencadenamiento de alarmas
  • Escribir código robusto y defensivo para manejar posibles problemas en la función de devolución de llamada
  • Aplicar tus conocimientos de funciones de devolución de llamada a otras áreas de la programación en C, como sistemas basados en eventos o operaciones asincrónicas

Comprender la función de devolución de llamada

En este paso, aprenderás sobre el concepto de funciones de devolución de llamada en el lenguaje C y cómo se utilizan en el desarrollo de programas en C para Linux.

Las funciones de devolución de llamada son una forma de pasar una función como argumento a otra función, que luego puede llamar a la función pasada en un momento posterior. Esta es una técnica poderosa que permite un código más flexible y modular.

En el código proporcionado en el archivo callback.c, la función de devolución de llamada se utiliza para implementar un sistema de alarma. La estructura alarm representa una alarma, y la función register_alarm se utiliza para registrar una alarma. Luego, la función hit_alarm se utiliza para desencadenar las alarmas registradas.

✨ Revisar Solución y Practicar

Identificar y corregir los defectos

Ahora, echemos un vistazo al código proporcionado en el archivo callback.c y corregamos los defectos.

  1. Error de segmentación: Esto probablemente se debe a que alarm_list no se está poblando o accediendo correctamente, lo que conduce a un acceso ilegal a la memoria.
  2. Manejo incorrecto de índices en register_alarm: La variable index es local a register_alarm y se reinicializa a 0 cada vez que se llama a la función. Esto hace que todas las alarmas se registren en el índice 1, sobrescribiéndose mutuamente.

Actualice el archivo callback.c de la siguiente manera:

#include "callback.h"

alarm alarm_list[MAX_ALARMS];
int current_index = 0; // Global index tracker

void register_alarm(alarm a) {
    if (current_index < MAX_ALARMS) {
        alarm_list[current_index] = a;
        current_index++;
    }
    // If the number of registered alarms exceeds MAX_ALARMS, do nothing (don't report an error)
}

int hit_alarm(int index) {
    if (index < 0 || index >= MAX_ALARMS ||!alarm_list[index])
        return 1;
    (*alarm_list[index])(index);
    return 0;
}

Los cambios clave son:

  1. Se agregó una variable global current_index para controlar el índice actual para registrar alarmas.
  2. En register_alarm, comprobamos si current_index es menor que MAX_ALARMS antes de registrar la alarma. Si el número de alarmas registradas excede MAX_ALARMS, no reportamos un error y simplemente continuamos.
  3. En hit_alarm, agregamos comprobaciones adicionales para asegurarnos de que el índice esté dentro del rango válido y de que una alarma esté realmente registrada en ese índice. Si no es así, devolvemos 1 para indicar que no se desencadenó ninguna alarma.
✨ Revisar Solución y Practicar

Probar la función de devolución de llamada

Ahora que hemos corregido los defectos en el archivo callback.c, probemos la función de devolución de llamada ejecutando el programa test_callback.c proporcionado.

Compile el programa:

gcc test_callback.c callback.c -o test_callback

Ejecute el programa:

./test_callback

Salida:

Alarm1:0
Alarm2:1
Alarm3:2

La salida ahora debería coincidir con la salida esperada, y el programa debería ejecutarse sin ningún error de segmentación u otros errores.

¡Felicitaciones! Has depurado y corregido con éxito la implementación de la función de devolución de llamada.

✨ Revisar Solución y Practicar

Resumen

¡Felicitaciones! Has completado este proyecto. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.