Pues la idea es hacer algo parecido a los delegados de C# pero con el C de toda la vida.
Sobre una lista dinámica de diferentes funciones con la misma firma se puede hacer las siguientes operaciones:
· Añadir funciones al final de la lista
· Quitar la primera aparición de una función dada
· Vaciar la lista de una tacada
· Ejecutar todas las funciones de la lista de forma secuencial y con unos parámetros comunes dados en la llamada a la ejecución.
En este programa se trabaja sobre una función que acepta un char* y no devuelve nada, pero se puede modificar fácilmente para trabajar con otras funciones.
Código
#include <stdio.h> #include <stdlib.h> typedef struct tdelegate { void (*func)(char*); struct tdelegate *next; } DELEGATE; int delegate_add(DELEGATE **pdelegate, void (*funcpointer)(char*)) { DELEGATE *aux = NULL; if(newdelegate == NULL) return 0; newdelegate->func = funcpointer; newdelegate->next = NULL; if(*pdelegate == NULL) *pdelegate = newdelegate; else { aux = *pdelegate; while(aux->next != NULL) aux = aux->next; aux->next = newdelegate; } return 1; } void delegate_exec(DELEGATE **pdelegate, char *str) { DELEGATE *actualdelegate = *pdelegate; while(actualdelegate != NULL) { actualdelegate->func(str); actualdelegate = actualdelegate->next; } } void delegate_del(DELEGATE **pdelegate, void (*funcpointer)(char*)) { DELEGATE *actualdelegate = *pdelegate; DELEGATE *aux = NULL; int found = 0; if(funcpointer == NULL || actualdelegate == NULL) return; if(actualdelegate->func == funcpointer) { aux = actualdelegate->next; actualdelegate = aux; } else { while(actualdelegate->next != NULL && !found) { if(actualdelegate->next->func == funcpointer) { found = 1; aux = actualdelegate->next->next; actualdelegate->next = aux; } else actualdelegate = actualdelegate->next; } } } void delegate_free(DELEGATE **pdelegate) { DELEGATE *aux = NULL; if(*pdelegate == NULL) return; while(*pdelegate != NULL) { aux = (*pdelegate)->next; *pdelegate = aux; } } /* FUNCIONES DE PRUEBA */ void a(char *str) { } void b(char *str) { } void c(char *str) { } /* PROGRAMA DE PRUEBA */ int main() { DELEGATE *midelegado = NULL; delegate_add(&midelegado, &a); delegate_add(&midelegado, &b); delegate_add(&midelegado, &c); delegate_exec(&midelegado, "hola"); delegate_del(&midelegado, &b); delegate_exec(&midelegado, "adios"); delegate_free(&midelegado); midelegado = NULL; return 0; }