container_of ( )

来源:互联网 发布:什么是网络通信 编辑:程序博客网 时间:2024/04/27 14:17
0> 思路:

              通过实例学习container_of( ), 分步解决2个问题:

                      1>>求结构体某成员到此结构体起始地址的[绝对距离].

                      2>>求结构体起始地址.


struct node_st {
          int id;
          int math;
          int phy;
   };


struct node_st  node1 = {
                  .id = 1,
                  .math = 99,
                  .phy = 88,

};


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1> 解决第<1>个问题:

 

已知: 结构体类型为 struct node_st, 求phy成员到结构体node1地址的绝对距离??

linux内核解决方法:

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

理解: (unsigned long) &((struct node_st *)0)->phy;

成员地址phy

0x8math

0x4id

0x0

这样得到绝对距离为8, 巧妙之处:借用0地址.(0地址巧用还有个NULL)

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2> 解决第<2>个问题:


已知:结构体类型为 struct node_st, phy成员及phy成员的地址, 求node1的地址???


内核解决方法:

 #define container_of(ptr, type, member) ({                    \
                           const typeof(((type *)0) ->member)*__mptr = (ptr);    \    /*疑问?这句多余吗*/  
                           (type *)((char *)__mptr -offsetof(type, member)); })

理解: container_of(&node1.phy,  struct node_st, phy)
          (struct node_st *) (char *)ptr - 8;


就是:用phy的实际地址(&node1.phy)减去绝对距离(8), 得到node1的地址;


NOTE:

          1>>   ({   }) 这种风格, 最后一句<;>就是结果.

          2>>    char *强转目的:按1个字节偏移


?疑问:

          这是内核的严谨, 可以判断&member的类型和ptr的类型是否一致!

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

总结:

          container_of(ptr, type, member) :

          输入3样:

                   <1>结构体类型type, <2>某一成员member, <3>member成员地址, 

         输出出结构体地址.   功能强大!!


         学习总结内核的代码技巧有益身心健康!!

                 




0 0
原创粉丝点击