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
- #include
-
- #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编译,运行,看看实际结果:
利用这个宏可以做哪些事情?