红联Linux门户
Linux帮助

linux源码,list_entry阅读心得

发布时间:2016-05-31 15:38:34来源:linux网站作者:han867241432

本人在linux源码上还是新手,希望大家不吝赐教。谢谢。


list_entry定义:

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


#define container_of(ptr, type, member) ({                      \
const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
(type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER);


这段代码描述了如何根据list_head来获取上层结构体中的数据。

/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/

ptr是所要提取数据的list_head的指针

type是外层结构的类型

member是list_head的变量名(专业名称不知道)。


const typeof( ((type *)0)->member ) *__mptr = (ptr); 

这句话目的是获取该list_head的地址,(type *)0)->member这句话是将0地址转为外层结构体类型后获取list_head,然后获取member的类型,也就是list_head,把ptr赋给它,至于为什么要这样操作,原因暂时还没搞清楚。


(type *)( (char *)__mptr - offsetof(type,member) );

这段代码是用list_head的地址减去list_head相对于外层结构地址的偏移量,从而获得外层地址。


#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

size_t 是unsigned int类型,将0转为外层地址类型,然后指向member也就是list_head,再取地址,就相当于获取了list_head的偏移地址。

__mpter和偏移地址作差即为外层结构地址。


其中不明白的点:

为什么要通过看上去比较复杂的方式获取__mpter;而不直接使用ptr;

希望知道的朋友能帮我解惑。

可能有写的不对的地方,希望大家批评指正,谢谢。


本文永久更新地址:http://www.linuxdiyf.com/linux/21123.html