第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 地址不会导致程序崩溃吗?

猜你喜欢

转载自www.cnblogs.com/shiwenjie/p/9201668.html