Linux内核中的conatainer_of()宏-
在代码中管理多个数据结构时,几乎总是需要将一个结构嵌入另一个结构中,然后随时检索它们,而不会被问到有关内存偏移量或边界的问题。假设您有一个struct person,定义如下:
struct person {
int age;
int salary;
char *name;
} p;
通过仅使用年龄或薪水指针,您可以检索包装(包含)该指针的整个结构。顾名思义,container_of宏用于查找结构给定字段的容器。该宏在include / linux / kernel.h中定义,如下所示:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
不要害怕指针。如下所示:
container_of(pointer, container_type, container_field);
以下是上述代码片段的元素:
- 指针:这是指向结构中字段的指针
- container_type:这是包装(包含)指针的结构的类型
- container_field:这是指针指向结构内部的字段的名称
让我们考虑以下容器:
struct person {
int age;
int salary;
char *name;
};
现在,让我们考虑其实例之一,以及指向age成员的指针:
struct person somebody;
[...]
int *age_ptr = &somebody.age;
与指向名称成员(age_ptr)的指针一起,可以使用container_of宏,以便通过使用以下命令来获取包装该成员的整个结构(容器)的指针:
struct person *the_person;
the_person = container_of(age_ptr, struct person, age);
container_of考虑了结构开始处的年龄偏移,以获取正确的指针位置。如果从指针age_ptr中减去字段年龄的偏移量,则将获得正确的位置。这是宏的最后一行:
(type *)( (char *)__mptr - offsetof(type,member) );
将其应用到一个真实的示例中,将得到以下结果:
struct family {
struct person *father;
struct person *mother;
int number_of_sons;
int family_id;
} f;
[...]
int *fam_id_ptr = &f.family_id;
struct family *fam_ptr;
fam_ptr = container_of(fam_id_ptr, struct family, family_id);
container_of宏主要用于内核中的通用容器。
这就是内核中的container_of宏。
rb_node
。