You should give your structs names. For example,
struct foo {
char * str1;
float tt1;
};
Then you can declare your instances like this:
struct foo var1 = { "This is me", 12 };
Then you can cast the void *
to a struct foo *
in your function:
void printStruct(void * ptr) {
printf("str=%s\n", ((struct foo *)ptr)->str1);
}
And you can call it like this:
int main(...) {
struct foo var1 = { "This is me", 12 };
printStruct(&var1);
}
Update: Commenter Johannes was correct, my answer doesn't account for the fact that the original poster said he might not know the type of each struct. Updated solution is below:
Since you know that all your structs contain a char * str1
, you can take advantage of C's "flat memory model" by casting your structs directly to generic, tagged struct that only contains char * str1
. This will only work if char * str1
is the first element of the structs.
struct base { char * str1; };
struct { char * str1; float tt1; } var1 = { "This is me", 12 };
struct { char * str1, int tt2; } var2 = { "This is me", 18 };
void printStruct(void * ptr) {
printf("str is %s\n", ((struct base *)ptr)->str1);
}
This is a pretty dirty hack, though, IMO. If there are other members that you want to share, you won't be able to use this same trick.
Another option is to define a struct
that uses a union with an enumerator to keep track of which type is actually being used in the union:
enum { FLOAT_TYPE, INT_TYPE };
struct foo {
char * str1;
union {
float tt1;
int tt2;
} numericValue;
int unionType;
};
This would let you define variables like this:
struct foo var1 = { .str1 = "This is me", .numericValue.tt1 =12, .unionType = FLOAT_TYPE };
struct foo var2 = { .str1 = "This is me", .numericValue.tt2 =18, .unionType = INT_TYPE };
Then you don't need to handle for different types of structs, you can cast your void pointer to struct foo *
instead:
void printStruct(void * ptr) {
struct foo * p = (struct foo *)ptr;
printf("string is %s\n", p->str1);
}
This might be require a bit more work but it's much cleaner, IMO.