乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      container_of()宏的簡要解析

       ydzhang 2009-09-19
      在學習Linux驅(qū)動的過程中,遇到一個宏叫做container_of。
      該宏定義在include/linux/kernel.h中,首先來貼出它的代碼:
      1.       439/** 
      2.       440 * container_of - cast a member of a structure out to the containing structure 
      3.       441 * @ptr:        the pointer to the member. 
      4.       442 * @type:       the type of the container struct this is embedded in. 
      5.       443 * @member:     the name of the member within the struct. 
      6.       444 * 
      7.       445 */ 
      8.       446 #define container_of(ptr, type, member) ({                      \ 
      9.       447        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \ 
      10.      448      (type *)( (char *)__mptr - offsetof(type,member) );})
       
      它的作用顯而易見,那就是根據(jù)一個結構體變量中的一個域成員變量的指針來獲取指向整個結構體變量的指針。比如,有一個結構體變量,其定義如下:
      1.       struct demo_struct { 
      2.           type1 member1; 
      3.           type2 member2; 
      4.           type3 member3; 
      5.           type4 member4; 
      6.       }; 
      7.        
      8.       struct demo_struct demo;
      同時,在另一個地方,獲得了變量demo中的某一個域成員變量的指針,比如:
      1.       type3  *memp = get_member_pointer_from_somewhere();
      此時,如果需要獲取指向整個結構體變量的指針,而不僅僅只是其某一個域成員變量的指針,我們就可以這么做:
      1.       struct demo_struct *demop = container_of(memp, struct demo_struct, member3);
      這樣,我們就通過一個結構體變量的一個域成員變量的指針獲得了整個結構體變量的指針。

      下面說一說我對于這個container_of的實現(xiàn)的理解:
      首先,我們將container_of(memp, struct demo_struct, type3)根據(jù)宏的定義進行展開如下:
      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) );})
      其中,typeof是GNU C對標準C的擴展,它的作用是根據(jù)變量獲取變量的類型。因此,上述代碼中的第2行的作用是首先使用typeof獲取結構體域變量member3的類型為 type3,然后定義了一個type3指針類型的臨時變量__mptr,并將實際結構體變量中的域變量的指針memp的值賦給臨時變量__mptr。
       
      (char *)__mptr轉(zhuǎn)換為字節(jié)型指針。(char *)__mptr - offsetof(type,member) )用來求出結構體起始地址(為char *型指針),然后(type *)( (char *)__mptr - offsetof(type,member) )在(type *)作用下進行將字節(jié)型的結構體起始指針轉(zhuǎn)換為type *型的結構體起始指針。


      假設結構體變量demo在實際內(nèi)存中的位置如下圖所示:
           demo
       +-------------+ 0xA000
       |   member1   |
       +-------------+ 0xA004
       |   member2   |
       +-------------+ 0xA010
       |   member3   |
       +-------------+ 0xA018
       |   member4   |
       +-------------+

      則,在執(zhí)行了上述代碼的第2行之后__mptr的值即為0xA010。

      再看上述代碼的第3行,其中需要說明的是offsetof,它定義在include/linux/stddef.h中,其定義如下:
      1.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
      先分析一下這個宏的運行機理:
      一共4步 
      1. ( (TYPE *)0 ) 將零轉(zhuǎn)型為TYPE類型指針;
      2. ((TYPE *)0)->MEMBER 訪問結構中的數(shù)據(jù)成員;
      3. &( ( (TYPE *)0 )->MEMBER )取出數(shù)據(jù)成員的地址;
      4.(size_t)(&(((TYPE*)0)->MEMBER))結果轉(zhuǎn)換類型。巧妙之處在于將0轉(zhuǎn)換成(TYPE*),結構以內(nèi)存空間首地址0作為起始地址,則成員地址自然為偏移地址;
       
      同樣,我們將上述的offsetof調(diào)用展開,即為:
      1. (struct demo_struct *)( (char *)__mptr - ((size_t) &((struct demo_struct *)0)->member3) );
      可見,offsetof的實現(xiàn)原理如上所述,就是取結構體中的域成員相對于地址0的偏移地址,也就是域成員變量相對于結構體變量首地址的偏移。

      因此,offsetof(struct demo_struct, member3)調(diào)用返回的值就是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的首地址(如上圖所示)。

       
      這就是從結構體某成員變量指針來求出該結構體的首指針。指針類型從結構體某成員變量類型轉(zhuǎn)換為該結構體類型。
      由此,container_of實現(xiàn)了根據(jù)一個結構體變量中的一個域成員變量的指針來獲取指向整個結構體變量的指針的功能。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多