亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

理解Linux contain_of()宏

2019-11-06 09:23:11
字體:
來源:轉載
供稿:網友

linux contain_of()宏

container_of()函數

1.該宏定義在include/linux/kernel.h中

439/**

440 * container_of - cast a member of a structure out to the containing structure

441 * @ptr:        the pointer to the member.

442 * @type:       the type of theContainer struct this is embedded in.

443 * @member:     the name of the member within the struct.

444 *

445 */

446 #define container_of(ptr, type, member) ({                      /

447        const typeof( ((type *)0)->member ) *__mptr = (ptr);    /

448      (type *)( (char *)__mptr - offsetof(type,member) );})

它的作用顯而易見,那就是根據一個結構體變量中的一個域成員變量的指針來獲取指向整個結構體變量的指針。比如,有一個結構體變量,其定義如下:

struct demo_struct {

          type1 member1;

           type2 member2;

           type3 member3;

           type4 member4;

      };

     struct demo_struct demo;

同時,在另一個地方,獲得了變量demo中的某一個域成員變量的指針,比如:

type3  *memp = get_member_pointer_from_somewhere();

此時,如果需要獲取指向整個結構體變量的指針,而不僅僅只是其某一個域成員變量的指針,我們就可以這么做:

struct demo_struct *demop = container_of(memp, struct demo_struct, member3);

這樣,我們就通過一個結構體變量的一個域成員變量的指針獲得了整個結構體變量的指針。

下面說一說我對于這個container_of的實現的理解:

首先,我們將container_of(memp, struct demo_struct, type3)根據宏的定義進行展開如下:

struct demo_struct *demop = ({                      /

const typeof( ((struct demo_struct *)0)->member3 ) *__mptr = (memp);    /

(struct demo_struct *)( (char *)__mptr - offsetof(struct demo_struct, member3) );})

其中,typeof是GNU C對標準C的擴展,它的作用是根據變量獲取變量的類型。因此,上述代碼中的第2行的作用是首先使用typeof獲取結構體域變量member3的類型為 type3,然后定義了一個type3指針類型的臨時變量__mptr,并將實際結構體變量中的域變量的指針memp的值賦給臨時變量__mptr。

(char *)__mptr轉換為字節型指針。(char *)__mptr - offsetof(type,member) )用來求出結構體起始地址(為char *型指針),然后(type *)( (char *)__mptr - offsetof(type,member) )在(type *)作用下進行將字節型的結構體起始指針轉換為type *型的結構體起始指針。

 

假設結構體變量demo在實際內存中的位置如下圖所示:

     demo

 +-------------+ 0xA000

 |   member1   |

 +-------------+ 0xA004

 |   member2   |

 +-------------+ 0xA010

 |   member3   |

 +-------------+ 0xA018

 |   member4   |

 +-------------+

 

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

 

再看上述代碼的第3行,其中需要說明的是offsetof,它定義在include/linux/stddef.h中,其定義如下:

1.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

先分析一下這個宏的運行機理:

一共4步

1. ( (TYPE *)0 ) 將零轉型為TYPE類型指針;

2. ((TYPE *)0)->MEMBER 訪問結構中的數據成員;

3. &( ( (TYPE *)0 )->MEMBER )取出數據成員的地址;

4.(size_t)(&(((TYPE*)0)->MEMBER))結果轉換類型。巧妙之處在于將0轉換成(TYPE*),結構以內存空間首地址0作為起始地址,則成員地址自然為偏移地址;

 

同樣,我們將上述的offsetof調用展開,即為:

1. (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的首地址(如上圖所示)。

 

這就是從結構體某成員變量指針來求出該結構體的首指針。指針類型從結構體某成員變量類型轉換為該結構體類型。

由此,container_of實現了根據一個結構體變量中的一個域成員變量的指針來獲取指向整個結構體變量的指針的功能。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本精品中文字幕| 国产美女高潮久久白浆| 日韩欧美国产一区二区| 日韩精品在线视频观看| 午夜精品一区二区三区在线视频| 国产亚洲欧美日韩一区二区| 国产精品电影网站| 国产精品福利久久久| 国产精品福利无圣光在线一区| 精品亚洲aⅴ在线观看| 在线播放国产精品| 亚洲综合最新在线| 日韩av片永久免费网站| 国产精品视频永久免费播放| 亚洲福利视频网| 日韩中文字幕av| 成人欧美在线观看| 欧美在线国产精品| 日韩av免费看| 久久久成人的性感天堂| 国产综合久久久久久| 美日韩丰满少妇在线观看| 国产成人一区二区三区| 欧美激情中文字幕在线| 国产精品中文字幕在线观看| 欧美日韩ab片| 日韩欧美高清视频| 亚洲精品v天堂中文字幕| 国产精品永久免费观看| 日韩精品在线免费观看视频| 国产日韩在线播放| 欧美国产日韩一区二区三区| 91免费视频网站| 91久久在线播放| 欧美人在线观看| 欧美国产一区二区三区| 亚洲男人天堂2019| 国产精品视频不卡| 91精品啪在线观看麻豆免费| 97在线视频观看| 久久久噜噜噜久久中文字免| 91黑丝在线观看| 国内精品久久久久久久| 亚洲综合中文字幕在线| 深夜福利日韩在线看| 久久国产精品久久久久久久久久| 国产精品成人v| 欧美做爰性生交视频| 亚洲精品免费av| 亚洲人成在线播放| 尤物九九久久国产精品的分类| 久久精品国产清自在天天线| 欧洲精品久久久| 欧美激情在线观看视频| 欧美精品日韩三级| 欧美成人黄色小视频| 国产在线不卡精品| 色哟哟入口国产精品| 视频在线观看99| 欧美成人性色生活仑片| 国产精品视频地址| 国产精品中文字幕在线| 亚洲免费成人av电影| 国产精品视频免费观看www| 欧美另类69精品久久久久9999| 亚洲国语精品自产拍在线观看| 久久九九热免费视频| 日韩麻豆第一页| xvideos国产精品| 亚洲一区二区精品| 国产99久久精品一区二区 夜夜躁日日躁| 粗暴蹂躏中文一区二区三区| 亚洲美女性视频| 97福利一区二区| 97香蕉久久超级碰碰高清版| 亚洲免费伊人电影在线观看av| 日韩免费在线看| 日韩av免费在线| 久久成人亚洲精品| 57pao成人国产永久免费| 亚洲欧洲免费视频| 亚洲精品中文字| 欧美成人免费小视频| 欧美日本在线视频中文字字幕| 欧美国产日韩一区二区三区| 2021久久精品国产99国产精品| 久久91精品国产| 国产综合视频在线观看| 亚洲mm色国产网站| 91精品久久久久久久久青青| 欧美中文字幕视频在线观看| 91国语精品自产拍在线观看性色| 91精品久久久久久久久久| 国产欧美日韩91| 亚洲国产成人91精品| 久久久久久com| 精品欧美国产一区二区三区| 色综合天天综合网国产成人网| 国产精品69精品一区二区三区| 国产精品中文字幕久久久| 亚洲精品免费网站| 亚洲va男人天堂| 欧洲亚洲妇女av| 精品二区三区线观看| 亚洲欧洲日本专区| 欧美性猛交xxxx乱大交| 欧洲一区二区视频| 欧美一区二区大胆人体摄影专业网站| 国产成人一区二| 国产日韩专区在线| 欧美另类暴力丝袜| 欧美男插女视频| 久久国产一区二区三区| 色悠悠久久久久| 亚洲一区二区三区久久| 亚洲最大激情中文字幕| 92看片淫黄大片看国产片| 久久久久久久久电影| 久久精品一偷一偷国产| 亚洲精品中文字幕有码专区| 欧美激情乱人伦一区| 国产成人精品免高潮费视频| 欧美成人精品一区二区三区| 成人精品视频久久久久| 欧美一级淫片videoshd| 欧美国产日韩一区二区在线观看| 91精品国产色综合久久不卡98| 国产偷国产偷亚洲清高网站| 国产午夜精品全部视频在线播放| 久久精品国产2020观看福利| 精品高清一区二区三区| 亚洲二区中文字幕| 中文字幕av日韩| 国产亚洲a∨片在线观看| 国产视频在线一区二区| 91成人天堂久久成人| 国产免费久久av| 97在线日本国产| 成人免费网站在线看| 欧美国产在线视频| 亚洲国产成人久久| 国产亚洲一区二区精品| 日韩综合中文字幕| 成人av在线网址| 欧美成人午夜影院| 91精品久久久久久| 成人黄色免费网站在线观看| 亚洲国产精品va在线看黑人| 久久精品国产69国产精品亚洲| 深夜福利日韩在线看| 国产一区二区三区高清在线观看| 日韩视频免费观看| 久久国产精品影片| 亚洲视频国产视频| 中文字幕自拍vr一区二区三区| 欧美做受高潮1| 亚洲国产欧美一区二区丝袜黑人| 成人福利视频网| 精品亚洲永久免费精品| 亚洲人成电影网站色xx| 国产欧美精品在线| 日韩大片免费观看视频播放| 国产精品久久久久久久午夜| 国产精品偷伦视频免费观看国产|