Container_of是Linux内核中一个很常用的宏,其作用为:用结构体成员指针获得结构变量本身的指针。这里来分析一下它的实现。
首先,该宏定义在Linux 内核 include/linux/kernel.h 中
/**
* 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) );})
ptr:表示结构体中member的地址
type:表示结构体类型
member:表示结构体中的成员
根据前面所述,就是通过ptr的地址可以返回type类型的结构体变量首地址。其实它的实现很简单,都是对C指针的灵活应用。
const typeof( ((type *)0)->member ) *__mptr = (ptr);
定义一个中间变量__mptr,指向某个成员的指针ptr。
这个中间变量的命名规则:
"__"代表内部使用,内核编程中常常这么做;
“m"代表middle。
(type *)( (char *)__mptr - offsetof(type,member) );
通过中间变量__mptr(指向某个成员的指针)减去这个成员结构体中的偏移来得到结构体的指针。
其中偏移的获取offsetof宏的实现:
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
如有疑问,欢迎留言探讨。