container_of
June 2nd, 2009
container_of est une macro très utile et définie dans le kernel linux (./include/linux/kernel.h), qui permet de récupérer l’adresse d’une structure à partir d’un de ses membres:
/*! * container_of - cast a member of a descriptor out to the containing descriptor * * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
Elle prend en paramètres (comme décrit plus haut):
- ptr: le pointeur que nous manipulons, membre de la structure instanciée dont nous voulons récupérer l’adresse
- type: le type de la structure qui contient ce membre,
- member: le nom du membre dans la déclaration de la structure.
La premiere ligne de la macro permet de déclarer un pointeur qui va contenir l’adresse du membre.
Ce pointeur va être correctement déclaré grâce au cast réalisé par:
typeof( ((type *)0)->member )*
(type *) 0 permet de déclarer un pointeur de structure de type (type) à l’adresse 0. On récupère alors le membre qui nous intéresse et plus précisément son type avec typeof, opérateur unaire comme sizeof défini par gcc (http://gcc.gnu.org/onlinedocs/gcc/Typeof.html).
La deuxième ligne peut se décomposer en deux parties:
