entry()宏

————————————————————————————————–

/**

* 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_struct within the struct.

*/

#define list_entry(ptr, type, member) \

((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

————————————————————————————————–

指针ptr指向结构体type中的成员member;通过指针ptr,返回结构体type的起始地址,如图2。

type

|———-|

| |

| |

|———-|

ptr–> | member –|

|———-|

| |

| |

|———-|

图2 list_entry()宏的示意图

为了便于理解,在此给予进一步说明。

例如my_list结构:

struct my_list{

void *mydata;

struct list_head list;

}; struct list_head *pos;

则list_entry(pos, mylist, list)宏,就可以根据pos的值,获取mylist的地址,也就是指向mylist的指针,这样,我们就可以存取mylist->mydata字段了。

可为什么能够达到这样的效果?

list_entry(pos, mylist, list) 展开以后为:

((struct my_list *)((char *)(pos) – (unsigned long)(&((struct my_list *)0)->list)))

这看起来会使大多数人眩晕,但仔细分析一下,实际很简单。

((size_t) &(type *)0)->member)把0地址转化为type结构的指针,然后获取该结构中member成员的指针,并将其强制转换为size_t类型。于是,由于结构从0地址开始定义,因此,这样求出member的成员地址,实际上就是它在结构中的偏移量。

,当你能梦的时候就不要放弃梦

entry()宏

相关文章:

你感兴趣的文章:

标签云: