explorer

万丈高楼平地起,勿在浮沙筑高台

0%

[What]linux -> container_of

分析内核中的 container_of 宏。

在文件 include/linux/kernel.h 中定义了 container_of 宏:

功能是: 通过 ptr 反推出包含它结构体的地址.

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct
{
int a;
int b;
int c;
}numStr;


numStr str_num;

/**
* @note: 注意第一个参数是地址!
*/
numStr *pstr_num = container_of(&str_num.b, numStr, b);

分析

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @brief: 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
* @memver: 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));})

#define offsetof(TYPE,MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  • const typeof(((type *)0)->member) *__mptr = (ptr);
    • 创建了一个指向 member 成员的指针, 然后将现有的 ptr 地址赋值给 __mptr, 也就是说目前 __mptr 表示了 ptr 的实际地址.
  • (type *)((char *)__mptr - offsetof(type, member));
    • offsetof 计算出 member 成员在结构体 type 中偏移的字节数, 然后通过现有的 __mptr 与字节偏移作差值,便得出了 ptr 所在的结构体的地址.
Last Updated 2020-08-20 四 17:38.
Render by hexo-renderer-org with Emacs 26.3 (Org mode 9.3.7)