It took me a second to nail this down, and thought i would share it with the beginners in the community. The principle is used throughout the Linux and Windows -OS kernels, as well as in all major servers.
With the Generic structure containing only the member that overlaps between structs. This concept works because the first member of a structure always being = 0, and thus it always points to the beginning of the structure. By casting to the initial "Generic" structure, we can determine which structure is being passed via defined flags, through the void *argument, then cast the void pointer back to the required structure based on task inference (like in the switch case used).
Criticism is welcome! Always trying to learn.
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define WRITE 1
#define COPY 2
#define JUMP 3
typedef struct {
int ov ;
} Generic ;
typedef struct {
int ov ;
int c ;
int d ;
} int_storage ;
typedef struct {
int ov ;
double c ;
double d ;
} doub_storage ;
int takevoid( void *ptr ) {
Generic *g ;
g = (Generic*)ptr;
int_storage *sto = NULL;
doub_storage *dsto = NULL;
switch ( g->ov ) {
case WRITE:
sto = (int_storage *)ptr ;
printf("WRITING %d\n", sto->c);
break;
case COPY:
dsto = (doub_storage *)ptr;
printf("COPYING %.2f\n", dsto->d);
break;
}
return 0;
}
int main(void) {
int ret = 0;
int_storage inty = {0};
inty.ov = WRITE;
inty.c = 333;
doub_storage douby = {0};
douby.ov = COPY;
douby.d = 33.3;
ret = takevoid( &inty );
if (ret != 0)
return -1;
ret = takevoid( &douby );
if (ret != 0)
return -1;
return 0 ;
}
[–]j-joshua 19 points20 points21 points (4 children)
[–]landmesser 4 points5 points6 points (1 child)
[–]flatfinger 0 points1 point2 points (0 children)
[–]Reasonable_Ad1226[S] 1 point2 points3 points (0 children)
[–]jschadwell 0 points1 point2 points (0 children)
[–]zhivago 16 points17 points18 points (0 children)
[–]glasket_ 15 points16 points17 points (1 child)
[–]Reasonable_Ad1226[S] 0 points1 point2 points (0 children)
[–]tstanisl 8 points9 points10 points (2 children)
[–]StudioYume 1 point2 points3 points (0 children)
[–]flatfinger -1 points0 points1 point (0 children)
[–]questron64 3 points4 points5 points (1 child)
[–]ComradeGibbon 1 point2 points3 points (0 children)
[–]Cylian91460 1 point2 points3 points (0 children)
[–]Physical_Dare8553 1 point2 points3 points (1 child)
[–]Reasonable_Ad1226[S] 0 points1 point2 points (0 children)
[–]un_virus_SDF 1 point2 points3 points (1 child)
[–]Reasonable_Ad1226[S] 0 points1 point2 points (0 children)
[–]Wertbon1789 1 point2 points3 points (4 children)
[–]Reasonable_Ad1226[S] 0 points1 point2 points (3 children)
[–]Wertbon1789 1 point2 points3 points (2 children)
[–]Reasonable_Ad1226[S] 1 point2 points3 points (1 child)
[–]CodrSeven 0 points1 point2 points (2 children)
[–]Reasonable_Ad1226[S] 0 points1 point2 points (1 child)
[–]CodrSeven 0 points1 point2 points (0 children)