内核中常用宏定义——container_of详解
简介
container_of 是一个宏,通常在 C 语言编程中用于在嵌入式系统或内核开发中。它用于通过指向结构体成员的指针来获取指向包含该成员的结构体的指针。
简单来说,它的主要作用是根据结构体中的已知的成员变量的地址,来寻求该结构体的首地址。
宏定义
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) *__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
宏参数
- ptr: 指向结构体成员的指针。
- type: 结构体的类型。
- member: 结构体中成员的名称。
工作原理
typeof(((type *)0)->member): 获取 member 成员的类型。通过假设 0 地址处有一个 type 类型的结构体,使用 -> 运算符获取 member 成员的类型。
const typeof(((type *)0)->member) *__mptr = (ptr): 定义一个指向 member 类型的常量指针 __mptr,并将其初始化为 ptr。
(type *)((char *)__mptr - offsetof(type, member)): 通过将 __mptr 转换为 char * 类型指针,然后减去 member 成员在结构体 type 中的偏移量来获取指向结构体 type 的指针。
使用示例
#include <stdio.h>
#include <stddef.h> // For offsetof macro
struct my_struct {
int a;
float b;
char c;
};
int main() {
struct my_struct example = { 1, 2.0f, 'A' };
char *ptr_to_c = &example.c;
struct my_struct *container = container_of(ptr_to_c, struct my_struct, c);
printf("container->a: %d\n", container->a);
printf("container->b: %f\n", container->b);
printf("container->c: %c\n", container->c);
return 0;
}
container->a: 1
container->b: 2.000000
container->c: A
- 假设 ptr_to_c 是指向 example.c 的指针。
- 计算 c 在 struct my_struct 中的偏移量,即 offsetof(struct my_struct, c)。
- 将 ptr_to_c 转换为 char *,然后减去 c 的偏移量,得到 example 结构体的地址。
总结
container_of 宏是一个强大的工具,用于通过结构体成员的指针获取指向包含该成员的结构体的指针。在内核开发和嵌入式编程中,它广泛用于处理嵌套数据结构和回调机制。