container_of是一个宏定义,用于通过一个结构体成员的指针来获取该结构体的起始地址。
在内核的C语言编程中,由于一些数据结构通常有类似的布局和逻辑,所以可能会有这样的需求:在已知一个结构体成员的指针时,获取该结构体的起始地址,以便进一步操作该结构体的其他成员。这种情况下,就可以使用container_of宏。
container_of的定义如下:
#define container_of(ptr, type, member) \
((type *) ((char *) (ptr) - offsetof(type, member)))
宏参数的含义是:
ptr:指向结构体中的某个成员的指针,
type:结构体的类型,
member:结构体中的某个成员。
宏的返回值是一个转换后的指针,指向结构体的起始地址。
下面通过一个例子来说明container_of的使用。
假设有如下定义的结构体类型:
struct person {
char name[20];
int age;
float height;
};
现在我们有一个指向该结构体成员的指针,我们想要获取到该结构体的起始地址。
struct person *p = (struct person *) malloc(sizeof(struct person));
strcpy(p->name, "John");
p->age = 25;
p->height = 1.7;
现在我们有一个指向height成员的指针,我们可以使用container_of宏来获取到该结构体的起始地址,如下所示:
float *ph = &(p->height);
struct person *ptr = container_of(ph, struct person, height);
在这个例子中,指针ph指向height成员的地址,我们用container_of宏将ph转化为指向结构体person的指针ptr,ptr将指向结构体person的起始地址,即p。
下面是container_of宏的实现原理。宏定义的核心是通过指定成员的指针(ptr)和成员在结构体中的偏移量(offsetof)来计算结构体的起始地址。
宏的实现如下:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
宏的实现利用了typeof和offsetof两个C语言关键字。
1. typeof是GCC的一个扩展,用于获取给定表达式的类型。在这里,我们使用typeof( ((type *)0)->member )来获取成员的类型。
2. offsetof是C标准库中的一个宏,用于获取结构体成员在结构体中的偏移量。
3. 宏定义使用了C语言中的括号表达式,用于计算结构体起始地址。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/
发表评论 取消回复