container_of用法及实现

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/

点赞(67) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部