linux设备驱动程序学习笔记——container_of宏

   在open函数中,int (*open) (struct inode *inode,strcut file *flip); inode->i_cdev结构包含了我们在注册时配置的cdev结构,但是我们实际真正需要的是包含cdev结构的scull结构,在open中,我们应当获得这个scull结构的指针,方便以后的操作。如何获得,要利用到container_of宏。

该宏定义在<linux/kernel.h>中

#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

typeof 用于确定某个变量的实际类型,offsetof宏用于确定某个成员在结构体中的偏移值。

第一句话,仅仅是用来定义一个跟member同类型的指针,这里可理解为临时变量。我们在定义一个宏时,如果也需要和参数相同的临时变量,就可以采用这种方法。这里的(type*)0,假定有一个在0地址的type类型指针,因为这不牵涉到读写,所以安全上没有问题。这里的0可以为任意都可以,在这里仅仅是获得变量类型,它和下面的offsetof宏不同。

第二句话:用member的地址减去member在type中的偏移,就得到了包含这个member的type的首地址。

 

offsetof宏定义在[include/linux/stddef.h]中:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

 

这里的技巧是假定有一个在0地址的TYPE类型指针,那么将它的MEMBER地址获得,并转为size_t(int)类型,这就是MEMBER的偏移了。很巧妙的思路。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章