从kernel里面抠出的一些与宏container_of有关的代码,如下:
1、此宏作用是从结构体的某元素(member)出发,得到结构体的首地址;
2、container_of的参数解释
(1)type:指的是(包含member这个成员元素的结构体)所对应的类型,即(我们要获取首地址的那个结构体)所对应的类型;
(2)member:指的是结构体中的某个元素的名字,我们就是从这个元素出发,得到结构体的首地址。注意这个元素在内核中可能也是结构体。
(3)ptr:指向结构体中member这个元素的指针。
3、offsetof的解释
(1)格式这样看比较明显(->优先级比&高):#define offsetof(TYPE, MEMBER) ( (size_t) &( (TYPE *)0 )->MEMBER )
- 首先(TYPE *)0 ,然后(TYPE *)0 ->MEMBER,接着&((TYPE *)0 ->MEMBER),最后强制类型转换为size_t类型。
(2)进一步解释
- 即先将0地址强制转换为(要获取首地址的那个)结构体的指针;
- 然后获取元素member,进而取其地址。由于结构体的指针指向地址为0,那么元素member的地址就是member元素偏移结构体首地址的偏移量。
- 由于此时偏移量是以地址形式(就一个数字,或者说指针)呈现的,我们要把它改成int类型,所以来一个强制类型转换。
4、container_of解释
(1)const typeof( ((type *)0)->member )* __mptr = (ptr)
首先获取结构体元素member的的类型,然后定义一个指向此类型的指针_mptr,并赋值为ptr;
(2)(type *) ( (char *)__mptr - offsetof(type, member) )
首先将_mptr强制转化为char*类型,然后减去偏移量,最后强制转换为结构体类型指针,即返回了结构体首地址。
这里之所以转换为char*类型,是因为减去偏移量时,偏移量是多少,那就减去多少字节。