Code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef enum { f_unknown, f_int, f_float, f_char, f_foo } foo_t;
struct foo
{
foo_t type;
void *data;
};
void fill( struct foo *f, foo_t t, void *v )
{
f->type = t;
f->data = v;
}
char *lookup( foo_t f )
{
switch( f )
{
case f_int: return "int";
case f_float: return "float";
case f_char: return "char";
case f_foo: return "struct foo";
case f_unknown: break;
}
return "unknown";
}
char *dataof( struct foo *f )
{
static char buf[ BUFSIZ ];
switch( f->type )
{
case f_int: sprintf( buf, "%d", *((int*)(f->data)) ); break;
case f_float: sprintf( buf, "%f", *((float*)(f->data)) ); break;
case f_char: sprintf( buf, "%c", *((char*)(f->data)) ); break;
case f_foo: sprintf( buf, "%s", "not converted" ); break;
default: sprintf( buf, "%s", "unknown" );
}
return buf;
}
int main( void )
{
char c = 'a';
int i = 1;
float f = 2.34;
struct foo o = { f_foo, NULL };
struct foo data[4];
size_t x;
fill( data + 0, f_int, &i );
fill( data + 1, f_foo, &o );
fill( data + 2, f_char, &c );
fill( data + 3, f_float, &f );
for( x = 0; x < sizeof data / sizeof data[0]; x++ )
{
printf( "data[ %d ].type is \'%s\', and data[ %d ].data is %s\n",
x, lookup( data[ x ].type ), x, dataof( &data[ x ] ) );
}
return 0;
}
/*
data[ 0 ].type is 'int', and data[ 0 ].data is 1
data[ 1 ].type is 'struct foo', and data[ 1 ].data is not converted
data[ 2 ].type is 'char', and data[ 2 ].data is a
data[ 3 ].type is 'float', and data[ 3 ].data is 2.340000
*/
Typecasting back and forth is fine. You just have to make sure you're doing it right. Here's a quick hack.
Quzah.