container_of是一个C语言中比较少见,但实际在Linux kernel和zephyr rtos中都经常用到的宏。
它的作用是通过结构体成员的指针获取整个结构体的指针。通常用于实现一些数据结构或者在底层编程中进行指针操作。
在Linux kernel中的原型定义为:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
在zephyr rtos中的原型定义为:
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define CONTAINER_OF(ptr, type, field) \
((type *)(((char *)(ptr)) - offsetof(type, field)))
其中,__builtin_offsetof
是C编译器的内置宏。它是GCC编译器提供的一个特殊宏,用于计算结构体成员的偏移量。
先通过一个实际的例子来看container_of的作用:
#include <stdio.h>
#include <stddef.h>
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define CONTAINER_OF(ptr, type, field) \
((type *)(((char *)(ptr)) - offsetof(type, field)))
struct person {
const char name[20];
int age;
float weight;
};
void print_person_info(const char *input_name)
{
struct person *p = CONTAINER_OF(input_name, struct person, name);
printf("name is %s\n", p->name);
printf("age is %d\n", p->age);
printf("weight is %.1f\n", p->weight);
}
static struct person liming = {
.name = "liming",
.age = 18,
.weight = 55.5,
};
int main(int argc, char *argv[])
{
print_person_info(liming.name);
return 0;
}
使用gcc编译,运行,看看实际结果:
利用这个宏可以做哪些事情?