linux内核中的一些有趣的宏

来源:互联网 发布:水平位移监测数据分析 编辑:程序博客网 时间:2024/05/16 18:43

在Linux中遍历链表会得到所需节点中后向指针成员的地址,而不是节点本身的地址。为了获取节点的地址,linux内核中引入了list_entry这个宏。

#define  list_enty(ptr,type,member)  container_of(ptr,type,member)

这个宏的作用是通过指向member的指针ptr来获得指向整个节点的指针,member是type结构体的成员。

这个宏里还有另外一个宏container_of,此条宏位于linux/kernel.h中,定义如下:

#define  container_of(ptr,type,member)   ({const typeof(((type*)0) ->member)*_mptr = (ptr);\

(type*)((char*)_mptr - offsetof(type,member));})

该条宏包含两条语句:

1.const typeof(((type*)0) ->member)*_mptr = (ptr);

其含义为将地址0转换为type类型的指针,然后引用其中的member成员,定义一个指针_mptr其类型与member成员的数据类型一致,并用ptr对它初始化。

2.(type*)((char*)_mptr - offsetof(type,member));

其中offsetof有另一条宏来定义:

#define  offsetof(type,member)  ((size_t) &(type*)0 ->member)

此条宏作用是取出member成员与节点首地址的偏移量,其精彩之处在于设定一个节点地址为0的结构体,再找出其member成员的地址。

这样成员的地址即为成员地址与首地址的偏移量。

size_t型为unsigned int型。

语句2中将_mptr转换为char*型再与offsetof相减时就是以字节为单位相减。

因此用member成员的地址减去偏移量即为本节点的首地址。

 

原创粉丝点击