第31课 - 老生常谈的两个宏
Posted Hengs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第31课 - 老生常谈的两个宏相关的知识,希望对你有一定的参考价值。
第31课 - 老生常谈的两个宏
1. Linux 内核中常用的两个宏定义
1.1 offsetof 宏
- 在 include/linux/stddef.h 头文件中定义
- TYPE 是结构体类型、MEMBER 是结构体中一个成员的成员名
- 作用:offsetof 宏返回的是 MEMBER 成员相对于整个结构体变量的首地址的偏移量,类型是 size_t(unsigned int)
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
1.2 container_of 宏
/** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );})
- 在 include/linux/kernel.h 头文件中定义
- type 是结构体类型、member是该结构体的某一个成员、ptr 是指向成员 member 的指针
- container_of 宏使用 offsetof 宏完成其功能
- 作用:container_of 宏通过结构体变量中一个成员的地址得到这个结构体变量的首地址
上面这两个宏在 Linux 内核中非常常见,比如 linux 内核链表 list_head、工作队列 work_struct 中。乍一看,这两个宏给人感觉很复杂,尤其是 container_of 宏。其实,再复杂的结构也是由简单的东西构造而成的,下面我们就一层一层的剥开这两个宏的真相!!!
2. 逐步分析这两个宏
2.1 分析 offsetof 宏
offsetof 用于计算 TYPE 结构体中 MEMBER 成员的偏移位置。
第一次看到这个宏定义,第一反应就是直接使用 0 地址不会导致程序崩溃吗?
以上是关于第31课 - 老生常谈的两个宏的主要内容,如果未能解决你的问题,请参考以下文章