Une technique standard consiste à fournir une variable info de type rapide en tant que paramètre et de l'activer, puis de transmettre toutes les données par référence. à l'intérieur de la fonction, nous récupérons la valeur avec un casting explicite. Le type void * n'est pas coché par le compilateur, de sorte que le danger envoie un type qui n'est pas géré par la fonction (erreur de segmentation, corruption de données ou résultat de comportement inconnu). Commencez par configurer une énumération des types dont vous avez besoin:
Dans ce cas, j'utilise la convention TYPE_FUNCTION pour représenter une fonction renvoyant un type.
La directive enum choisit des entiers successifs à partir de 0, ou vous pouvez attribuer à chaque énumération sa propre valeur int.
typedef enum D_types {
ANINT, // don't use actual system type names
AFLOAT,
ADOUBLE,
ASTRING,
MY_STRUCT=100,
MY_STRUCT2=200
VOID_FUNCTION=1000,
INT_FUNCTION = 2000,
STRUCT_FUNCTION=3000
} DATATYPE;
/* an f_int is a function pointer to a function */
typedef int (*f_int)(int, void*);
Dans votre définition de la fonction que vous envoyez à la fois les données de référence et le type et jette le type correct avant utilisation:
int myfunction (DATATYPE dt, void* data, )
{
int an_int = 0;
int * ip; // typed pointers for casting of the void pointer data
double * dp;
char * sp;
struct My_struct * msp;
struct My_struct_2 * ms2p;
f_int fp;
...
switch (dt){
case ANINT:
ip = (int*) data; // only pointers can be assigned void pointer values.
int i = *ip // dereference of typed pointer, no dereferencing void pointers.
...
break;
case ADOUBLE:
dp = (double*) data;
double d = *dp;
...
break;
case ASTRING:
char * s = strdup((char*) data); // cast to char pointer allowed (pointer->pointer)
...
break;
case MY_STRUCT:
msp = (struct My_Struct *) data;
char* ms_name = msp->name; // if my_struct has a name string ...
float dollarvalue = msp->dvalue;
...
case INT_FUNCTION:
fp = (f_int)data;
an_int = fp(ANINT, 5);
}
return an_int;
}
Comme vous pouvez le deviner, ce joue avec des allumettes dans une usine de feux d'artifice, et pas encouragé comme une pratique constante.
dans votre code que vous appelez comme ceci:
double pi =3.14159;
int g = myfunction(ADOUBLE, &pi ); // pass by reference, not value
int j = myfunction (ASTRING , "HEY NOW"); //C strings pass by ref normally
f_int myfunc = myfunction; // a function pointer (ref to the functions address)
int r = myfunction (INT_FUNCTION, myfunc); /* function as a parameter ... */
Autre que pour une fonction unique il est recommandé d'utiliser les fonctions varargs http://www.eskimo.com/~scs/cclass/int/sx11b.html