ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux中的list_entry和container_of(转载)

2021-01-09 14:02:14  阅读:186  来源: 互联网

标签:MEMBER container list member typeof entry type ptr


转自http://hi.baidu.com/mynana/blog/item/1da1ba99239ceb006f068c48.html

list_entry宏是用来根据list_head指针查找链表所嵌入的结构体的地址,具体实现是依赖宏container_of:

#define list_entry(ptr, type, member)  container_of(ptr, type, member)

container_of的定义如下:

复制代码

 1 /**
 2  * container_of - cast a member of a structure out to the containing structure
 3  * @ptr:    the pointer to the member.
 4  * @type:   the type of the container struct this is embedded in.
 5  * @member: the name of the member within the struct.
 6  *
 7  */
 8 #define container_of(ptr, type, member) ({          \
 9     const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
10     (type *)( (char *)__mptr - offsetof(type,member) );})

复制代码

在这个宏定义中用到了另外两个宏:typeof 和 offsetof

对 typeof 的理解:
实际上, typeof 并不是宏定义,它是GCC的关键字,是GCC特有的特性。如果只知道一个变量的名字要得到其类型,并不是宏定义能够完成的,这需要编译时的信息。所以,typeof 操作是GCC内置的功能,在内核头文件和Glibc头文件中都是找不到typeof的宏定义的。

 

对 offsetof 的理解:
offsetof 是一个真正的宏,它定义在内核源代码 include/linux/stddef.h 文件中:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
在这里,TYPE表示一个结构体的类型,MEMBER是结构体中的一个成员变量的名字。offsetof 宏的作用是计算成员变量 MEMBER 相对于结构体起始位置的内存偏移量,以字节(Byte)为单位。
它的计算原理是,把整数0进行强制类型转换,转换为一个 TYPE 类型的指针,相当于0地址处的一个TYPE类型的指针; 然后找到成员变量 MEMBER; 最后用取地址符 & 得到 MEMBER 的地址。 因为结构体是从地址0处开始的,所以 MEMBER 的地址就是其相对于结构体起始位置的偏移量(由于TYPE类型的指针位于0地址处,取MEMBER成员的地址后就 得到了MEMBER成员在TYPE类型中的地址偏移值,最后转为size_t类型)。

对 container_of 的理解:
container_of有三个参数, ptr是成员变量的指针, type是指结构体的类型, member是成员变量的名字。 container_of 的作用就是在已知某一个成员变量的名字、指针和结构体类型的情况下,计算结构体的指针,也就是计算结构体的起始地址。 计算的方法其实很简单,就是用该成员变量的指针减去它于type结构体起始位置的偏移量。
 #define container_of(ptr, type, member) ({ \
 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

在这个定义中,typeof( ((type *)0)->member ) 就是获得 member 的类型, 然后定义了一个临时的常量指针 __mptr, 指向 member 变量。 为什么不直接使用 ptr 而要多此一举呢? 我想可能是为了避免对 ptr 及prt 指向的内容造成破坏。 把 __mptr 转换成 char * 类型, 因为 offsetof 得到的偏移量是以字节为单位。 两者相减得到结构体的起始位置, 再强制转换成 type 类型。

标签:MEMBER,container,list,member,typeof,entry,type,ptr
来源: https://blog.csdn.net/luobaotai/article/details/112390836

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有