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

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

    • 分享

      list_entry的宏定義

       jason zhai 2010-09-19

      轉(zhuǎn)載  list_entry的宏定義 收藏

      list_entry的宏定義:
      #define list_entry(ptr, type, member) \ 
      ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
      這個(gè)倒是不難理解:從一個(gè)結(jié)構(gòu)的成員指針找到其容器的指針。
      但是正因?yàn)槿绱耍业牡谝桓杏X是,這個(gè)宏的名字應(yīng)該更加抽象,名字似乎應(yīng)該改稱叫“尋找容器”一類的,查看list.h源代碼,發(fā)現(xiàn)現(xiàn)在的定義是這樣的:
      #define list_entry(ptr, type, member) \
          container_of(ptr, type, member)

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

      #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
      linux不想用C++,但又想利用C++的優(yōu)點(diǎn),如是出現(xiàn)了很多奇怪的宏,他們叫做trick。
      ptr是找容器的那個(gè)變量的指針,把它減去自己在容器中的偏移量的值就應(yīng)該得到容器的指針。(容器就是包含自己的那個(gè)結(jié)構(gòu))。指針的加減要注意類型,用(char*)ptr是為了計(jì)算字節(jié)偏移。((type *)0)->member是一個(gè)小技巧。自己理解吧。前面的(type *)再轉(zhuǎn)回容器的類型。
      =====================
      #define list_entry(ptr, type, member) \
              ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

          ptr是指向list_head類型鏈表的指針,type為一個(gè)結(jié)構(gòu),而member為結(jié)構(gòu)type中的一個(gè)域,類型為list_head,這個(gè)宏返回指向type結(jié)構(gòu)的指針。在內(nèi)核代碼中大量引用了這個(gè)宏,因此,搞清楚這個(gè)宏的含義和用法非常重要。

        
      設(shè)有如下結(jié)構(gòu)體定義:
      typedef struct xxx
      {
           ……(結(jié)構(gòu)體中其他域,令其總大小為size1)
           type1 member;
           ……(結(jié)構(gòu)體中其他域)
      }type;


      定義變量:
         type a;
         type * b;
         type1 * ptr;
      執(zhí)行:
         ptr=&(a.member);
         b=list_entry(ptr,type,member);
      則可使b指向a,得到了a的地址。

      如何做到的呢?

      先看&((type *)0)->member:
      把“0”強(qiáng)制轉(zhuǎn)化為指針類型,則該指針一定指向“0”(數(shù)據(jù)段基址)。因?yàn)橹羔樖恰皌ype *”型的,所以可取到以“0”為基地址的一個(gè)type型變量member域的地址。那么這個(gè)地址也就等于member域到結(jié)構(gòu)體基地址的偏移字節(jié)數(shù)。

       


      再來看 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))):
      (char *)(ptr)使得指針的加減操作步長為一字節(jié),(unsigned long)(&((type *)0)->member)等于ptr指向的member到該member所在結(jié)構(gòu)體基地址的偏移字節(jié)數(shù)。二者一減便得出該結(jié)構(gòu)體的地址。轉(zhuǎn)換為 (type *)型的指針,大功告成。

      ==============

       list_entry定義如下:

      /**
      * list_entry - get the struct for this entry
      * @ptr:        the &struct list_head pointer.
      * @type:        the type of the struct this is embedded in.
      * @member:        the name of the list_struct within the struct.
      */
      #define list_entry(ptr, type, member) \
              ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
      ===================

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多