如果想在用户程序中使用内核的 struct list_head 数据结构,那么可以参考 scripts/kconfig/list.h 中的实现,甚至可以将其直接拷贝出来使用。
struct list_head 可以连接任何带有 struct list_head 元素的结构体。它的使用方法也很简单,主要分为以下几个步骤:
- 通过 LIST_HEAD() 初始化一个 struct list_head 头结点,即初始化一个链表
- 定义带有 struct list_head 元素的结构体
- 通过 list_add_tail() 等接口将上述结构体实例中的 struct list_head 元素连接到链表中
- 通过 list_entry()、list_for_each_entry() 等接口从链表中获取结构体实例
下面看代码示例:
#include <stdio.h>
#include <string.h>
#include "list.h"
struct struct1 {
const char *name;
struct list_head list;
int value1;
};
struct struct2 {
const char *name;
struct list_head list;
int value2;
};
int main(void)
{
struct struct1 a = {
"struct1 -- a",
LIST_HEAD_INIT(a.list),
100,
};
struct struct1 b = {
"struct1 -- b",
LIST_HEAD_INIT(b.list),
101,
};
struct struct2 c = {
"struct2 -- c",
LIST_HEAD_INIT(c.list),
102,
};
struct struct2 d = {
"struct2 -- d",
LIST_HEAD_INIT(d.list),
103,
};
LIST_HEAD(g_list);
list_add_tail(&a.list, &g_list);
list_add_tail(&b.list, &g_list);
list_add_tail(&c.list, &g_list);
list_add_tail(&d.list, &g_list);
struct struct1 *p;
struct struct2 *q;
list_for_each_entry(p, &g_list, list) {
if (strncmp(p->name, "struct1", 7) == 0)
printf("name=%s, value=%d\n", p->name, p->value1);
else {
q = (struct struct2 *)p;
printf("name=%s, value=%d\n", q->name, q->value2);
}
}
return 0;
}
运行结果:
$ gcc main.c -o main
$ ./main
name=struct1 -- a, value=100
name=struct1 -- b, value=101
name=struct2 -- c, value=102
name=struct2 -- d, value=103
当然,平时一般也没人这么用,为了使用方便,链表上的结构体类型最好一致。