One of the standard methods is to provide a type variable of type information as a parameter and turn it on and pass all the data by reference. inside the function we restore the value with explicit casting. The void * type is not checked by the compiler, so the danger sends a type that is not processed by the function (segmentation error, data corruption, or the result of unknown behavior). start by setting up an enumeration of the types you need:
In this case, I use the TYPE_FUNCTION convention to represent a function that returns a type.
The enum directive selects consecutive integers from 0, or you can assign each enumeration its own int value.
typedef enum D_types { ANINT,
In the function definition, you send both the data by reference and the type and use it to the correct type before use:
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; }
As you might have guessed, this plays with matches in a factory firework, and is not encouraged as a constant practice.
in your code, you would call it like this:
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 ... */
Except for a one-time function, it is recommended that you use the varargs functions http://www.eskimo.com/~scs/cclass/int/sx11b.html