侵入式链表
普通链表
学习数据结构的时候写的链表是下面这个样子的
typedef struct LNode
{
int data; /* 数据域 /
int num; / 数据域 */
struct LNode pre; / 指向下一个结点 */
struct LNode next; / 指向上一个结点 */
}
侵入式链表
在 RT-Thread 以及 Linux 内核中链表是这样定义的
struct rt_list_node
{
struct rt_list_node next; / 指向下一个结点 */
struct rt_list_node prev; / 指向上一个结点 /
};
typedef struct rt_list_node rt_list_t; / 链表类型 */
在使用的时候是这样定义的
struct rt_object
{
rt_uint8_t type; /* 类型 /
rt_uint8_t flag; / 标志 /
...
rt_list_t list; / 链表结点 */
};
每一个内核对象定义的时候,让结构体包含一个成员变量,这个成员变量是一个通用的链表结点。
二者区别
普通的链表和侵入式链表的区别在于
普通的链表结点的指针域存放的是 下一个结点的内存首地址
侵入式链表结点的指针域存放的是 下一个结点的链接域成员变量的内存首地址
普通的链表有了结点的内存首地址之后,该结点的其它成员变量很轻松就可以访问到
那既然侵入式链表存放的是 下一个结点的链接域成员变量的内存首地址,如果想获取下一个结点的所有成员变量该如何操作呢,这里就需要使用到 list_entry 这个宏了
list_entry
宏 list_entry 用来通过结构体的成员指针来返回整个结构体的地址,有了结构体的地址,那么结构体其它成员就可以访问到了
该宏的实现如下:
#define rt_list_entry(node, type, member)
rt_container_of(node, type, member)
#define rt_container_of(ptr, type, member)
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
具体宏的解析参见:list_entry/container_of
原作者:tyustli
|