container_of
时间: 2023-08-10 17:28:55 浏览: 43
`container_of` 是一个 Linux 内核中的宏,用于从一个结构体中获取包含它的另一个结构体的指针。这个宏通常被用于实现内核中的链表或红黑树等数据结构。
例如,如果有一个结构体 `struct node`,其中含有一个叫做 `list` 的成员变量,而这个结构体 `node` 又是一个叫做 `list_node` 的结构体中的一个成员,那么我们可以通过下面的代码来获取包含 `list` 成员变量的 `list_node` 结构体的指针:
```c
struct list_node {
int data;
struct node list; // 包含另一个结构体
};
struct node {
char* name;
int age;
};
struct list_node* ptr = ...; // 指向一个 list_node 结构体的指针
struct node* node_ptr = container_of(ptr, struct node, list);
```
这里的第一个参数是我们要获取指针的结构体成员的指针,第二个参数是包含这个成员的结构体类型,第三个参数是成员的名称。在这个例子中,我们从 `ptr` 指针中获取包含 `list` 成员变量的 `list_node` 结构体的指针,并将其转换为 `node` 结构体的指针,以便我们可以访问 `name` 和 `age` 成员变量。
相关问题
container_of宏
container_of宏是Linux内核中常用的宏之一。它可以根据结构体的成员变量地址,找到整个结构体的地址。
具体来说,假设有一个结构体A,其中包含一个成员变量B,现在要根据B的地址,找到整个A的地址。可以使用container_of宏,其定义如下:
```c
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
```
其中,ptr为成员变量B的地址,type为结构体A的类型,member为结构体A中成员变量B的名称。
使用container_of宏的示例代码如下:
```c
struct A {
int a;
int b;
};
struct A my_a;
int *ptr_b = &my_a.b;
struct A *ptr_a = container_of(ptr_b, struct A, b);
```
在上面的代码中,首先定义了一个结构体A,其中包含两个成员变量a和b。然后,定义了一个A类型的变量my_a,并将成员变量b的地址赋值给ptr_b。最后,使用container_of宏得到整个结构体A的地址,并将其赋值给ptr_a。
通过container_of宏,我们可以方便地在Linux内核中访问嵌套的结构体,从而简化代码的编写和维护。
container_of原理
container_of宏的原理是通过已知结构体成员变量的地址,来获取整个结构体的首地址。它是在Linux内核中定义的宏,实现方式如下:
1. 首先,使用offsetof宏来计算出成员变量相对于结构体首地址的偏移量。
```
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
```
2. 接下来,使用typeof来获取成员变量的类型,然后定义一个临时指针__mptr,并将传入的成员变量的地址赋值给它。
```
const typeof(((type *)0)->member) *__mptr = (ptr);
```
3. 最后,通过将__mptr指针减去偏移量的方式,得到整个结构体的首地址,并将其强制转换为指向结构体类型的指针。
```
(type *)((char *)__mptr - offsetof(type, member));
```
这样,container_of宏就可以根据已知的成员变量地址,推算出整个结构体的首地址。从而可以直接访问结构体的其他成员。
引用可以更详细地了解container_of宏的使用示例。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *2* *3* [Linux 内核 container_of 宏详解](https://blog.csdn.net/m0_37383484/article/details/129244244)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"]
[ .reference_list ]