/* * This example show how get sibling members of a struct. Suppose that you * have a struct foo with members A and B. With the macros provided here you can * get the address of B, having a pointer to A and knowing that B is the B member * of struct foo. This is not my work, is just based on macros provided by gcc * compiler __builtin_offsetof() and the container_of() macro found on linux * kernel sources. */ #include <stdio.h> /* * You can get the offset of a member on a struct by dereferencing that member on * address 0 of such structure. */ #define offset_of(type, member) ((unsigned long) &((type *)0)->member) /* * With the capability to get offsets, is possible to get the address of the * struct that contains some data. We just need a pointer to that data and the * offset of that data on the struct. With this informations we can calculate * the address of struct by subtracting the offset from the pointer to that data * contained on struct. In the macro above the @ptr is the data contained on * struct. */ #define container_of(ptr, type, member) \ ((type *) ((char *)ptr - offset_of(type, member))) struct foo { char *str; int len; }; void print_sibling(int *ip); int main(void) { struct foo bar = { .str = "Hello World", .len= 11, }; print_sibling(&bar.len); return 0; } /* * This function receives an int pointer (@ip) that is known to be the member "len" of * a "struct foo". With such information we can do the magic and take any * "sibling" member of that struct. */ void print_sibling(int *ip) { struct foo *tmp = container_of(ip, struct foo, len); puts(tmp->str); }
sexta-feira, 11 de novembro de 2011
container_of
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário