Linux中container_of实现分析


内核版本:linux-2.6.37.1

container_of的宏定义如下:

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

使用container_of宏后,可通过父结构体type中的成员member的已知地址ptr,来寻找当前ptr地址所属的父结构体type的地址。

例子:

  1. struct test{  
  2.     int     a,  
  3.     char  b,  
  4.     struct   tmp,  
  5. }  
  6.   
  7. struct test p;  
  8. p.tmp = &pt;  

使用container_of宏后可以通过已知的struct tmp地址pt来计算得到test的地址。下面结合根据例子分析container_of宏代码

  1. const typeof( ((type *)0)->member ) *__mptr = (ptr);  
将mptr指针将之转换成member类型的指针。这是通过首先将0地址强制转换成type类型的地址(即struct test地址)
  1. struct test{                      0x00000000  
  2.     int     a,                    0x00000000  
  3.     char  b,                      0x00000004  
  4.     struct   tmp,                 0x00000005  
  5. }  
然后通过typeof(X->member)来获得type类型中member的类型,再将mptr强制转换为member类型,最后对mptr赋已知的地址ptr。

这样最后只要通过ptr指针减去一个偏移量即可获得父结构体重type的地址。

  1. (type *)( (char *)__mptr - offsetof(type,member) );})  

结合例子总结:例如已知p.tmp的地址pt为0x30005646,通过offsetof(type,member)可以算的tmp在test中的偏移量为5,则计算可得父结构体p的地址为子结构体tmp的地址0x300005646减去tmp在父结构体中的偏移量5,即0x30005646-5 = 0x30005641

相关内容