大家好,我是极客范的本期栏目编辑小友,现在为大家讲解Linux内核基础-container_of问题。
/**
* container_of -将结构中的一个成员铸造到包含结构中
* @ptr:指向成员的指针。
* @type:嵌入此的容器结构的类型。
* @member:结构中成员的名称。
*
*/
#定义容器_of(ptr,类型,成员)({ \
const typeof(((type *)0)-(成员)* _ _ mptr=(ptr);\
(type *)((char *)_ _ mptr-offset of(type,member));})
在Linux内核中,容器被广泛使用。它用于通过结构的成员变量的地址来获取整个结构的入口地址。
首先,解释出现在宏定义中的另外两个关键词或宏定义。
Typeof:获取变量类型。
例如:
char * pc
(*pc) c的类型;
c=' a
在这个例子中,typeof(*pc)相当于char,所以变量c的类型是char类型变量。
Offsetof(类型,成员):类型结构中成员变量的偏移量。
#定义(类型,成员)的偏移量((大小_t)((类型*)0)-(成员)
类型是结构的类型,0是假想的类型结构,而成员是结构的成员。因为结构的基址是0,所以成员的地址是成员相对于结构头地址的偏移量。
下面描述了容器的具体实现:容器的(ptr,类型,成员):
const typeof(((type *)0)-(成员)* _ _ mptr=(ptr);
它意味着声明一个与成员类型相同的指针常量*__mptr,并将其初始化为ptr。请注意,type of((type *)0)-(member)是获取成员变量的类型。之前添加了Const,以确保以下0不被更改。
(type *)((char *)_ _ mptr-offset of(type,member));表示__mptr的地址减去结构中成员的偏移量,然后将其转换为类型指针。该指针是成员所在结构的入口地址。为什么我应该先转换成字符指针?如果_mptr是整形指针,_mptr-offset相当于减去sizeof (int) * offset字节。