2009年8月14日星期五

container_of, offsetof

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

/**
* container_of - cast a member of a structure out to the containing structure
* @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) );})

This marco is very useful, it will find a pointer pointing to the containner address.
I just use it for a long time, but don't know how it works, today I am going to check it out.

The first line find a pointer __mptr pointer to the member,
second line use __mptr to substract the offset the member's offset in the container.

I like the following trick,
((TYPE *)0)->MEMBER
Cast a '0' to the containter structure pointer,
->MEMBER , will give the offset accordingly.

The marco are inside kernel.h and stddef.h

沒有留言:

發佈留言