內核版本:linux-2.6.37.1
container_of的宏定義如下:
- #define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
使用container_of宏後,可通過父結構體type中的成員member的已知地址ptr,來尋找當前ptr地址所屬的父結構體type的地址。
例子:
- struct test{
- int a,
- char b,
- struct tmp,
- }
-
- struct test p;
- p.tmp = &pt;
使用container_of宏後可以通過已知的struct tmp地址pt來計算得到test的地址。下面結合根據例子分析container_of宏代碼
- const typeof( ((type *)0)->member ) *__mptr = (ptr);
將mptr指針將之轉換成member類型的指針。這是通過首先將0地址強制轉換成type類型的地址(即struct test地址)
- struct test{ 0x00000000
- int a, 0x00000000
- char b, 0x00000004
- struct tmp, 0x00000005
- }
然後通過typeof(X->member)來獲得type類型中member的類型,再將mptr強制轉換為member類型,最後對mptr賦已知的地址ptr。
這樣最後只要通過ptr指針減去一個偏移量即可獲得父結構體重type的地址。
- (type *)( (char *)__mptr - offsetof(type,member) );})
結合例子總結:例如已知p.tmp的地址pt為0x30005646,通過offsetof(type,member)可以算的tmp在test中的偏移量為5,則計算可得父結構體p的地址為子結構體tmp的地址0x300005646減去tmp在父結構體中的偏移量5,即0x30005646-5 = 0x30005641