歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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

Copyright © Linux教程網 All Rights Reserved