免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 801 | 回复: 0
打印 上一主题 下一主题

对Linux内核中container_of宏的理解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-11 21:45 |只看该作者 |倒序浏览

487   * container_of - cast a member of a structure out to the containing structure
488      * @ptr:           the pointer to the member.
489      * @type:          the type of the container struct this is embedded in.
490      * @member:        the name of the member within the struct.
491      *
492      */
493  #define container_of(ptr, type, member) ({                         \
494             const typeof( ((type *)0)->member ) *__mptr = (ptr);       \
495             (type *)( (char *)__mptr - offsetof(type,member) );})
每行前面的数字是所在的行数。 可见在这个宏定义中用到了另外两个宏:typeof 和 offsetof 。
对 typeof 的理解:
实际上, typeof
并不是宏定义,它是GCC的关键字,是GCC特有的特性。如果只知道一个变量的名字要得到其类型,并不是宏定义能够完成的,这需要编译时的信息。所
以,typeof 操作是GCC内置的功能,在内核头文件和Glibc头文件中都是找不到typeof的宏定义的。

对 offsetof 的理解:

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

对 container_of 的理解:

三个参数, ptr是成员变量的指针, type是指结构体的类型, member是成员变量的名字。 container_of
的作用就是在已知某一个成员变量的名字、指针和结构体类型的情况下,计算结构体的指针,也就是计算结构体的起始地址。
计算的方法其实很简单,就是用该成员变量的指针减去它相对于结构体起始位置的偏移量。
493  #define container_of(ptr, type, member) ({                         \
494             const typeof( ((type *)0)->member ) *__mptr = (ptr);       \
495             (type *)( (char *)__mptr - offsetof(type,member) );})
在这个定义中,typeof( ((type *)0)->member ) 就是获得 member 的类型, 然后定义了一个临时的常量指针 __mptr, 指向 member
变量。 为什么不直接使用 ptr 而要多此一举呢? 我想可能是为了避免对 ptr 及prt 指向的内容造成破坏。 把 __mptr 转换成
char * 类型, 因为 offsetof 得到的偏移量是以字节为单位。 两者相减得到结构体的起始位置, 再强制转换成 type 类型。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73525/showart_2092031.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP