container_of的实现分析
在linux内核中经常可以看到container_of的身影,也是linux引以为豪的地方之一了。《linux设备驱动开发详解》132页对container_of的作用作了说明——通过结构体成员的指针找到这个成员所在结构体的指针。但没有具体分析它是怎么实现的。
下面我们先看看这个宏的定义:
/**
* 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是结构体typ的成员member的指针,我们很多时候希望得到结构体type的起始地址,也就是type的指针。
假设这个type在内存中的存储模型如下:
type
|----------|
| |
| |
|----------|
ptr->| member --|
|----------|
| |
| |
|----------|
这里,我们拆开来就好理解了:
首先,(type *)0)是把0地址转化为TYPE结构的指针(这里把0换成其它值也是一样的);
((type *)0)->member type结构体中的member成员;
typeof( ((type *)0)->member ) 返回member的类型;
const typeof( ((type *)0)->member ) *__mptr = (ptr); 用上面这个类型定义一个指针__mptr,并把ptr赋值给它;
(char *)__mptr 把__mptr转化成char型指针;
offsetof宏定义在[include/linux/stddef.h]中定义为:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
这里,说明一下这个宏,((size_t) &((TYPE *)0)->MEMBER)把0地址转化为TYPE结构的指针,然后获取该结构中MEMBER成员的指针,并将其强制转换为size_t类型。于是,由于结构从0地址开始定义,因此,这样求出的MEMBER成员地址,实际上就是它在结构中的偏移量。这也显示出了C语言中指针的强大。因为,在某个体系结构下实现的libc,结构中各个成员的偏移总是可以预见的。
现在有了member成员在type结构体中的偏移量,又有了指向member的指针__mptr,自然就可以计算出type结构的起始地址了。
小小一个宏就包括了这么多精华,可见linux的博大。
原帖地址:http://hi.baidu.com/ayoxstswewboswd/item/d2826df20c5191de6325d21b
文章的脚注信息由WordPress的wp-posturl插件自动生成
微信扫一扫,打赏作者吧~![[已解决]nc命令报错 close: Bad file descriptor](http://www.jyguagua.com/wp-content/themes/begin/timthumb.php?src=http://www.jyguagua.com/wp-content/uploads/2022/03/Snipaste_2022-03-18_20-16-48.png&w=280&h=210&zc=1)
![[已解决]SecureCRT/SSH 连接Linux缓慢](http://www.jyguagua.com/wp-content/themes/begin/timthumb.php?src=http://www.jyguagua.com/wp-content/uploads/2020/07/ssh_slow.jpg&w=280&h=210&zc=1)
![[转载]Linux的tickless设置](http://www.jyguagua.com/wp-content/themes/begin/timthumb.php?src=http://www.litrin.net/wp-content/uploads/2018/11/kernel_menuconfig_tickless-1.png&w=280&h=210&zc=1)
![[整理]鲲鹏性能优化十板斧(五)——应用程序性能调优<TaiShan特战队出品>](http://www.jyguagua.com/wp-content/themes/begin/timthumb.php?src=http://www.jyguagua.com/wp-content/uploads/2020/03/1-4.jpg&w=280&h=210&zc=1)