现在的位置: 首页 > 综合 > 正文

list.h中宏list_entry宏的解析与应用

2013年10月02日 ⁄ 综合 ⁄ 共 2353字 ⁄ 字号 评论关闭

list_enty这个宏算是内核里面比较复杂的宏了。下面就对它的结构进行解析。宏的结构为:

 

这个宏的作用是通过ptr指针获取type的地址,其中ptr是member的指针,member是type结构的成员。

这个宏里面包含另外一个宏,container_of。这个宏位于/linux/kerner.h,它的结构为:

 

这个宏包含两条语句。第一条:const typeof( ((type *)0)->member ) *__mptr = (ptr);首先将0转化成type类型的指针变量(这个指针变量的地址为0×0),然后再引用member成员(对应就是((type *)0)->member ))。注意这里的typeof(x),是返回x的数据类型,那么 typeof( ((type *)0)->member )其实就是返回member成员的数据类型。那么这条语句整体就是将__mptr强制转换成member成员的数据类型,再将ptr的赋给它(ptr本身就是指向member的指针)。第二条语句里面的offsetof也是一个宏,它在/linux/stddef.h中这样定义:

 

((TYPE *)0)->MEMBER)这个其实就是提取TYPE类型中的member成员,那么&((TYPE *)0)->MEMBER)得到member成员的地址,再强制转换成size_t类型(unsigned int)。因为它的结构体地址从0开始定义,所以得到的member成员的地址就是它相对于结构体的偏移地址。再回到contanier_of的第二句话,把得到的member的地址强制转化成char *,(这里不是很理解,借用别人的思路),因为如果member是非char型的变量,比如为int型,并且假设返回值为offset,那么这样直接减去偏移量,实际上__mptr会减去sizeof(int)*offset!这和指针的自加自减运算一样,根据其指向的变量的类型不同而不同。(同意)

接下来,container_of宏的含义就不言而喻了,也就是list_entry宏。

下面是对该宏实现的一个应用实例,以加深理解。

 

运行结果如下:

 

$ ./offset 

address of &stu is=0xbf89bb18

 

addressx of &stu-num=0xbf89bb18 offset of stu->num is=0

 

addressx of &stu-name=0xbf89bb1c offset of stu->name is=4

 

addressx of &stu-sex=0xbf89bb1d offset of stu->sex is=5

 

computing address of &stu using:

address and offset of stu->num=0xbf89bb14

address and offset of stu->name=0xbf89bb17

address and offset of stu->sex=0xbf89bb18

 

 

 

 

 

 

 

抱歉!评论已关闭.