Quand utilisez-vous container_of macro?
Je sais ce que la macro ne.
Dans de nombreux niveau du noyau de codes, il est souvent utilisé pour parcourir liste liée.
Je veux trouver d'autres cas utiles.
Quand utilisez-vous container_of ou CONTAINING_RECORD macro?
Quand la macro extrêmement utile?
Vous devez vous connecter pour publier un commentaire.
container_of
vous permet de simplifier vos structures de données en omettant les pointeurs de parent structures.Il est utilisé à l'intérieur de la liste liée de mise en œuvre ainsi que la liste de nœud peut être un élément de structure, et n'importe qui peut trouver la structure mère sans avoir à transporter un explicite pointeur.
Un autre exemple est
struct work_struct
. Un workqueue fonction de travail reçoit une work_struct comme argument, et il l'habitude d'avoir un générique de "données" de la charge utile. Cette valeur de données a été supprimé, rendant la structure plus petite, comme la fonction de travail peut appelercontainer_of
à trouver sa structure mère.C'est une façon de tourner autour du fait que C n'ont pas de génériques ou des modèles.
Vous voulez une liste liée générique, donc il suffit de mettre des pointeurs à l'intérieur du nœud lui-même (de sorte que vous pouvez abstraction de la gestion de la structure elle-même), puis utilisez
CONTAINING_RECORD
pour trouver le reste des données dans votre propre code, par exemple:Maintenant, étant donné un
struct Node
, vous pouvez trouver saItem
en disant:struct NODE
nomméptr
, je pense que tu veux dire:CONTAINING_RECORD(ptr, Item, node)
Pour l'avenir searche(r)s: c'est la meilleure explication que j'ai trouvé jusqu'à présent:
http://psomas.wordpress.com/2009/07/01/weird-kernel-macros-container_of/
De coeur (je le cite):
"Maintenant, nous pouvons comprendre(au moins partiellement) l'exécution de la macro. Il déclare un pointeur vers le membre de la structure qui
ptr
points, et attribue ptr pour elle. Maintenant__mptr
points à la même adresse queptr
. Puis il obtient le décalage de cettemember
dans lestruct
, et soustrait à partir de l'adresse réelle de la membre de lastruct ‘instance’(ie __mptr)
. Le(char *)__mptr
exprimés est nécessaire, de sorte que "l'arithmétique des pointeurs" fonctionnent comme prévu, c'est à dire de soustraire de__mptr
exactement la(size_t)
octetsoffsetof
"revient"."et, en outre, deux autres indices (citation):
"À ce point, je ne comprends vraiment pas pourquoi on ne pourrait pas utiliser le pointeur ptr directement. Nous avons pu omettre la première ligne, et la macro peut être
ptr
est utilisé qu'une seule fois, nous n'avons pas besoin de vous soucier des effets secondaires.Peut-être que c'est juste les bonnes pratiques de codage."
et, au plus tard edit du post original (cité):
"Apparemment, la première ligne est là pour" type de contrôle. Il s'assure que
type
a un membre appelémember
(cependant cela se fait paroffsetof
macro aussi, je pense), et siptr
n'est pas un pointeur vers le bon type (le type de lamember
), le compilateur affiche un avertissement, ce qui peut être utile pour le débogage."Il ajuste un pointeur sur un membre d'une structure à un pointeur sur la structure, ce qui est utilisé de diverses manières dans le noyau, le plus commun pourrait être décrit comme un triste avec un décalage statique où la structure extérieure est dérivé (par inclusion) de l'intérieur, et que l'appelant invoque une méthode sur l'objet interne, qui est ensuite envoyé à une méthode sur l'objet extérieur.
Bien, que, sans OO support du compilateur.