list_for_each_entry解析

list_for_each_entry解析: 
#define list_for_each_entry(pos, head, member) \ 
for (pos = list_entry((head)->next, typeof(*pos), member) ; &pos->member != (head) ; pos = list_entry(pos->member.next, typeof(*pos), member))

将上面宏 for分解如下:

1 pos = list_entry((head)->next, typeof(*pos), member) :获得 pos 指向结构体的地址 
2 &pos->member != (head) 
3 pos = list_entry(pos->member.next, typeof(*pos), member)

解析: pos = list_entry((head)->next, typeof(*pos), member) 
#define list_entry(ptr, type, member) container_of(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)); }  )

((type *)0)->member  :
((type *)0):强制转换操作 强制将 0 转换为 type类型的指针,将0强制转换为一个地址,这个地址0x0000(32位系统)指向的是类型type的数据,当然这只是我们的技巧,并不是真的在地址0x0000存放了我们的数据 struct type *p = NULL;  p->member;为什么这么写????? 有啥好处咩????原因:((type *)0)->member  : 这里的 “->” 很明显是通过 指针 操作 结构体成员 ,成员变量是member 指针就是上面的通过0强制转换的地址。所以相当于地址 0X0000是结构体类型type的首地址,通过"->" 操作type类型的成员变量 member。

typeof(((type *)0)->member) * __mptr = (ptr) :
((type *)0)->member  的作用就是得到成员变量,再通过 typeof(((type *)0)->member) 就知道member的成员类型了int* p :我们知道这是定义一个int类型的指针,在一些比较通俗的函数里,需要定义一个指针,但是不巧的是不能确定指针的类型,所以在程序里面不能写死,那么晚这时候应该怎么办?? 这个时候就需要typeof帮我们搞定。typeof(((type *)0)->member) * __mptr = (ptr) : 就是利用这个技巧, 其中 typeof(((type *)0)->member)就是member的类型, __mptr是变量,所以这句话的意思是定义一个指针变量 __mptr ,指向的类型是member的类型它初始化的值是 ptr,ptr是container_of的第一个参数。

(type *)((char *)__mptr - offsetof(type, member)) :
__mptr是前面定义的member成员类型的指针,初始化为ptr。offsetof(type, member) 是求出member在 type类型结构体中的偏移量,两者相减就是 type类型结构体的地址。强制转换为 char类型 是因为地址是以字节为单元

总结:container_of(ptr, type, member) 的作用就是 获得总结构体的地址,我们需要提供的参数是:
                          ptr : member 成员的指针 
                          type: 结构体类型 
                          member: 成员member的名字

container_of(ptr, type, member) :                           
ptr指向的是 type.member类型的数据,用来推算出以ptr指向的对象作为成员的结构体的起始地址

list_for_each_entry(type, head, member) :                         
head 组成的链表是由 type.member 为节点连接成的, head是链表头,搜寻整个链表,对type类型的数据进行处理

猜你喜欢

转载自blog.csdn.net/linuxarmbiggod/article/details/79195455