1. ## Multi-struct function?

Hi

I have a number of different strut composite variables and a single function that I want to pass them to, is it possible through casting or another method to be able to pass these different struts to a single method?

Code:
```Struct A {
uint8_t data1;
uint16_t data2;
uint8_t data3;
} // structa

Struct B {
uint32_t data1;
uint16_t data2;
uint8_t data3;
uint16_t data4;
uint16_t data5;
uint8_t data5;
} // structb {

Struct C {
uint16_t data1;
uint16_t data2;
} // structc

Function1(StructA);
Function1(StructB);
Function1(StructC);

Void Function1(uint8_t anyStruct) {

For (i=0; I < sizeof(anyStruct); i++) {
// print each byte onto the console for example usage
} // for

} // function 1```
Many thanks :-)

David

2. You could pass a pointer to anything as a void *; however, the function itself would have no way of knowing which struct got passed in or how to deal with it in any meaningful way.

3. You can use a void pointer to pass a pointer to anything in.

Maybe you could use sizeof to get the size of the stuct within the function and print out each byte. Not sure if it would work as i have never tried it.

4. oh right, how would that look in code then? Something like this?

Code:
```Function1(StructA);
Function1(StructB);
Function1(StructC);

Void Function1(void* anyStruct) {

For (i=0; I < sizeof(anyStruct); i++) {
// print each byte onto the console for example usage
} // for

} // function 1```

5. Well, no.

sizeof(anyStruct) == sizeof(void *) == 4 (probably).
sizeof(void) is not defined.

6. In C, a function normally takes only one type of argument(s). You can make any pointer match a void *, so passing the address of your struct would work. sizeof() on a pointer, however, would not give you the right value.

You have two options, either:
* pass along which type of struct you actually passed in (you probably need to know which struct it is anyways) - and then determine the size using something like "if (type == 'A') size = sizeof(struct A);",
* Pass in the size of the struct itself.

Of course, there are other variants on the theme: You could put a common struct at the beginning of all structs, which contains one of or both the size and type of struct.

--
Mats

7. oh sorry, I was talking about actually passing the struct to the function, not the size of part :-)

8. Originally Posted by DavidDobson
oh sorry, I was talking about actually passing the struct to the function, not the size of part :-)
Yes, but using sizeof() on something that has been passed to a function, where "something" is a pointer to one of several different structures will not work - because your code will not know what the pointer is pointing to.

--
Mats

9. oh ic, I don't actually want to use size of at all, it was just for the example of what I want to do with the function What I need to do is pass any type of struct to a single function.

thanks

David

10. You could also pass a union as an argument, although that's sort of like what mats suggested earlier. Your function is defined by cases.

Code:
```struct A;
struct B;

union OneOfThese
{
struct A init_a;
struct B init_b;
};

void foo (union OneOfThese * item, int option)
{
switch (option) {
case 'a':
/* union is a A */
break;
case 'b':
/* union is a B */
break;
default:
}
}```
Or something like that anyway.

11. Switch to c++ and this becomes easy.

But the problem is one method can't do something with three different data formats. It would have to convert whatever data it needs into a standard format before using it. Or it would have to have a big switch statement for each type, in which case there is no point of having it be one method.

Your best option is to have several separate similarly named functions that convert the data to a common format to be used by the common function. If it is not possible to derive a common function that deals with the relevant data, but the structure of the code is the same for all variants, then you can use a macro for the common function, still keeping the struct specific functions to enforce type safety.

EDIT, for example the function above:
Code:
```void function1A(StructA);
void function1B(StructB);
void function1C(StructC);
void function1_impliment(int size, char *data);

void function1A(StructA *struct){
function1_impliment(sizeof(StructA), (char*)struct);
}

void function1B(StructB *struct){
function1_impliment(sizeof(StructB), (char*)struct);
}

void function1C(StructC){
function1_impliment(sizeof(StructC), (char*)struct);
}

void function1_impliment(int size, char *data){
for (i=0; I < sizeof(anyStruct); i++) {
putchar();
}
}```
Also to avoid code repletion you can use a macro like this:
Code:
```#define function1_body(type) \
void function1##type(type*struct){
function1_impliment(sizeof(type), (char*)struct);
}```
But you still need to call a different function for each type because C does not support overloading.

EDIT 2: I just realized that I am basically showing you how to implement templates in C. In C++ templates are much more common, though admittedly the code isn't much prettier.

12. In C++ you could do this an entirely different way...

Why not just do as many sub-systems of the Win32 API do?

Example:
Code:
```struct myImage
{
int size;
int height, width;
char pixels[];
};

struct mySprite
{
int size;
int imageId, x, y;
}

void doStuff(void *p)
{
switch(*(int *)p)
{
case sizeof(myImage):
...
case sizeof(mySprite):
...
}
}```
Where the size parameter is always set to size of the structure.

Just a thought...

13. Or more likely, in C++, you would use member functions and perhaps inheritance to solve the problem.

And that is of course a possible solution in C too - just use a common structure with function pointers that is at the beginning of all of the other structures, and call a function that does the right thing(s).

--
Mats

14. Originally Posted by King Mir
Code:
```void function1A(StructA *struct){
function1_impliment(sizeof(StructA), (char*)struct);
void function1B(StructB *struct){
function1_impliment(sizeof(StructB), (char*)struct);
void function1C(StructC){
function1_impliment(sizeof(StructC), (char*)struct);
void function1##type(type*struct){
function1_impliment(sizeof(type), (char*)struct);```
struct is a keyword.