container_of深入理解
container_of在linux頭文件kernel.h中定義,如下:
14#ifndef offsetof15#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)16#endif1718#ifndef container_of19/**20 * container_of - cast a member of a structure out to the containing structure21 * @ptr: the pointer to the member.22 * @type: the type of the container struct this is embedded in.23 * @member: the name of the member within the struct.24 *25 */26#define container_of(ptr, type, member) ({ /27 const typeof(((type *)0)->member) * __mptr = (ptr); /28 (type *)((char *)__mptr - offsetof(type, member)); })29#endif 這里在簡單插入對typeof的理解: typeof關鍵字是C語言中的一個新擴展。從語義上看,typeof 關鍵字將用做類型名(typedef名稱)并指定類型。 請注意,typeof構造中的類型名不能包含存儲類說明符,如extern或static。不過允許包含類型限定符,如const或volatile。 例如:? 1. struct demo_struct {
?? 2.???? type1 member1;
?? 3.???? type2 member2;
?? 4.???? type3 member3;
?? 5.???? type4 member4;
?? 6. };
?? 7.
?? 8. struct demo_struct demo;
?? struct demo_struct *demop = container_of(memp, struct demo_struct, member3);
首先,我們將container_of(memp, struct demo_struct, type3)根據宏的定義進行展開如下:
?? 1. struct demo_struct *demop = ({????????????????????? /
?? 2.???? const typeof( ((struct demo_struct *)0)->member3 ) *__mptr = (memp);??? /
?? 3.???? (struct demo_struct *)( (char *)__mptr - offsetof(struct demo_struct, member3) );})
假設結構體變量demo在實際內存中的位置如下圖所示:
???? demo
+-------------+ 0xA000
|?? member1????????????? |
+-------------+ 0xA004
|?? member2???????????? |
|??????????????????????????????? |
+-------------+ 0xA010
|?? member3???????????? |
|??????????????????????????????? |
+-------------+ 0xA018
|?? member4???????????? |
+-------------+
則,在執行了上述代碼的第2行之后__mptr的值即為0xA010。
同樣,我們將上述的offsetof調用展開,即為:
?? 3. (struct demo_struct *)( (char *)__mptr - ((size_t) &((struct demo_struct *)0)->member3) );
可見,offsetof的實現原理就是取結構體中的域成員相對于地址0的偏移地址,也就是域成員變量相對于結構體變量首地址的偏移。
因此,offsetof(struct demo_struct, member3)調用返回的值就是member3相對于demo變量的偏移。結合上述給出的變量地址分布圖可知,offsetof(struct demo_struct, member3)將返回0x10。
于是,由上述分析可知,此時,__mptr==0xA010,offsetof(struct demo_struct, member3)==0x10。
因此, (char *)__mptr - ((size_t) &((struct demo_struct *)0)->member3) == 0xA010 - 0x10 == 0xA000,也就是結構體變量demo的首地址(如上圖所示)。
轉載于:https://www.cnblogs.com/p2liu/archive/2011/05/24/6048784.html
總結
以上是生活随笔為你收集整理的container_of深入理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初识python之 APP store排
- 下一篇: JSONObject.fromObjec