container_of(ptr, type, member)为宏定义,作用:在已知结构体成员member、结构体成员地址ptr、结构体类型type条件下,返回成员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) );})
举个例子:
定义结构体 struct Person
{
char *name;
int age;
}person;
已知age的地址,可通过container_of(&person.age, struct Person, person.age)获得person的首地址。
分析如下:
一、扩展const typeof( ((type *)0)->member ) *__mptr = (ptr)为 const typeof(((struct Person)*0)->age) *__mptr = &person.age;
① ((struct Person)*0)->age 将0地址转化为struct Person类型,并指向age;
② typeof(((struct Person)*0)->age) 获得age的数据类型(int);
③const typeof(((struct Person)*0)->age) *__mptr = &person.age 将age的地址赋值给__mptr
二、扩展(type *)( (char *)__mptr - offsetof(type,member) )为 (struct Person *)((char *)__mptr - offsetof(struct Person, person.age));
① offsetof(struct Person, person.age) 获得age的地址偏移量;
②(struct Person *)((char *)__mptr - offsetof(struct Person, person.age)) age的地址 减去其偏移量 就是该结构类型的首地址
注: offsetof(type,member) 定义为: #define offsetof(t, m) ((size_t) (&((t *)0)->m))
在例子中扩展为 (size_t) (& (struct Person *)0->age) 表示: 0地址转化为struct Person类型,& (struct Person *)0->age既表示age的地址,又表示age在结构体中的偏移量(因为从0地址开始)
size_t 的作用应该是增加系统的可移植性,在32位系统中size_t是4字节的,在64位系统中,size_t是8字节的