吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

container_of()宏,太妙了~

嵌入式情報局 ? 來源:嵌入式情報局 ? 2023-09-10 10:59 ? 次閱讀

container_of(ptr, type, member)宏的作用

該宏的作用是通過結(jié)構(gòu)體成員的地址和結(jié)構(gòu)體類型推導(dǎo)出結(jié)構(gòu)體的地址,type是指結(jié)構(gòu)體的類型,member是成員在結(jié)構(gòu)體中的名字,ptr是該成員在type結(jié)構(gòu)體中的地址。

container_of(ptr, type, member)宏解析

linux 源碼的 toolsincludelinuxkernel.h文件下,container_of()的定義如下:

#ifndefcontainer_of
/**
*container_of-castamemberofastructureouttothecontainingstructure
*@ptr:thepointertothemember.
*@type:thetypeofthecontainerstructthisisembeddedin.
*@member:thenameofthememberwithinthestruct.
*
*/
#definecontainer_of(ptr,type,member)({
consttypeof(((type*)0)->member)*__mptr=(ptr);
(type*)((char*)__mptr-offsetof(type,member));})
#endif

container_of() 宏的定義中的 offsetof(TYPE, MEMBER)typeof() 初學(xué)者可能會對其很陌生,所以我們要先從理解 offsetof(TYPE, MEMBER)typeof() 的作用開始。

offsetof(TYPE, MEMBER)

本質(zhì)也是個宏定義,在 linux 源碼的 toolsincludelinuxkernel.h 文件下定義如下:

#ifndefoffsetof
#defineoffsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)
#endif

offsetof 宏中的 TYPE 是指結(jié)構(gòu)體的類型,MEMBER 是指結(jié)構(gòu)體中的某個成員,作用是求出該成員的在該結(jié)構(gòu)體中的偏移量。該宏首先將 0 (地址0)轉(zhuǎn)化為 TYPE * 的結(jié)構(gòu)體指針,表示地址為 0 的結(jié)構(gòu)體指針,然后通過取地址符 &((TYPE *)0)->MEMBER) 取出該結(jié)構(gòu)體指針中 MEMBER 成員的地址,最后再將地址值強(qiáng)轉(zhuǎn)為 size_t 類型(內(nèi)核中為 unsigned long 類型)即表示 MEMBER 成員在結(jié)構(gòu)體中的偏移量。要理解該過程需要了解對結(jié)構(gòu)體的內(nèi)存分布,如圖,結(jié)構(gòu)體的內(nèi)存分配是連續(xù)的,當(dāng)結(jié)構(gòu)體的地址為0時,成員的地址即為該成員的偏移量。

758a6386-4f09-11ee-a25d-92fbcf53809c.png

實(shí)例:

#include

#ifndefoffsetof
#defineoffsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)
#endif

typedefstruct_offset
{
charmember_0;
intmember_1;
charmember_2;
}offset;

intmain()
{
printf("%d
",offsetof(offset,member_0));
printf("%d
",offsetof(offset,member_1));
printf("%d
",offsetof(offset,member_2));


return0;

}

輸出:

75a02496-4f09-11ee-a25d-92fbcf53809c.png

offsetof實(shí)例結(jié)果輸出

typeof()

typeof()GNU C 中的一個關(guān)鍵字,和 sizeof() 一樣都是 C 語言中的關(guān)鍵字而不是函數(shù)。作用是返回傳入數(shù)據(jù)的類型。實(shí)例:

#include

intmain()
{
inta=3;
typeof(a)b=a;/*求出a變量的類型,并創(chuàng)建一個b變量*/


printf("a=%db=%d",a,b);

return0;
}

輸出:

75b50758-4f09-11ee-a25d-92fbcf53809c.png

img

container_of(ptr, type, member)

了解了 offsetof() 宏和 typeof 關(guān)鍵字之后就比較好理解 container_of 宏的作用了。

consttypeof(((type*)0)->member)*__mptr=(ptr)

該代碼的作用實(shí)際上是將 0 轉(zhuǎn)化為 type * 結(jié)構(gòu)體類型,再取出結(jié)構(gòu)體中的MEMBER成員 (type *)0)->member, 再通過 typeof 關(guān)鍵字獲取 MEMBER 成員的類型,并定義一個 MEMBER 成員類型的指針 const typeof(((type *)0)->member) * __mptr,將傳入的 ptr 指針賦值給 __mptr__mptr = (ptr)

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

該代碼是將獲取的 MEMBER 成員地址強(qiáng)轉(zhuǎn)為 char *(強(qiáng)轉(zhuǎn)的目的是考慮指針的加減的實(shí)質(zhì)是指針在內(nèi)存的偏移,偏移量為指針類型所占字節(jié)的個數(shù)),減去 MEMBER 成員在 type 結(jié)構(gòu)體中的偏移量,強(qiáng)轉(zhuǎn)為 type * 后得到結(jié)構(gòu)體的地址。實(shí)例:

#include

#ifndefoffsetof
#defineoffsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)
#endif

#ifndefcontainer_of
#definecontainer_of(ptr,type,member)({
consttypeof(((type*)0)->member)*__mptr=(ptr);
(type*)((char*)__mptr-offsetof(type,member));})
#endif

typedefstruct_container
{
charmember_0;
intmember_1;
charmember_2;
}container;

intmain(void)
{
container*a=NULL;
containerb={'a',2,'b'};

/*member_1在實(shí)例結(jié)構(gòu)體中的地址結(jié)構(gòu)體類型成員名*/
a=container_of(&b.member_1,container,member_1);
printf("a->member_0=%c
",a->member_0);
printf("a->member_1=%d
",a->member_1);
printf("a->member_2=%c
",a->member_2);

return0;
}

輸出:

75c25a34-4f09-11ee-a25d-92fbcf53809c.png


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11345

    瀏覽量

    210392
  • 源碼
    +關(guān)注

    關(guān)注

    8

    文章

    652

    瀏覽量

    29452
  • 結(jié)構(gòu)體
    +關(guān)注

    關(guān)注

    1

    文章

    130

    瀏覽量

    10872

原文標(biāo)題:container_of()宏,太妙了~

文章出處:【微信號:嵌入式情報局,微信公眾號:嵌入式情報局】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux內(nèi)核中container_of原理詳解

    Linux內(nèi)核中經(jīng)常可見container_of的身影,它在實(shí)際驅(qū)動的編寫中也是廣泛應(yīng)用。
    發(fā)表于 07-14 15:19 ?350次閱讀
    Linux內(nèi)核中<b class='flag-5'>container_of</b>原理詳解

    詳細(xì)聊聊container_of這個定義

    大家周末好,我是bug菌~ 今天主要是跟大家詳細(xì)聊聊container_of這個定義,非常經(jīng)典的,只是一直沒有抽時間細(xì)細(xì)品味,今天就跟大家一起來看看有何神奇之處。
    的頭像 發(fā)表于 11-13 09:45 ?747次閱讀

    揭開linux內(nèi)核中container_of的神秘面紗

    在linux 內(nèi)核中有一個大名鼎鼎的container_of(),這個是用來干嘛的呢?我們先來看看它在內(nèi)核中是怎樣定義的。呵呵,乍一看不知道是什么東東。我們先來分析一下container_
    發(fā)表于 11-11 10:02

    offsetofcontainer_of詳解

    offsetofcontainer_of詳解 1.offsetofcontainer_of
    發(fā)表于 10-13 16:35

    Labview Active Container引用AUTODESK控件后異常?

    使用Labview active container引用后,單個VI運(yùn)行是正常的,單將單個VI引入后,出現(xiàn)異常,這種問題需要怎樣解決,有相關(guān)經(jīng)驗(yàn)的人沒。
    發(fā)表于 05-19 18:31

    鴻蒙應(yīng)用開發(fā)-container動漫效果體驗(yàn)

    `container案例練習(xí)。 點(diǎn)擊按鈕觸發(fā)事件,兩個方塊顏色發(fā)生漸變。 Hml代碼如下:<!-- xxx.hml --><div class
    發(fā)表于 04-09 16:37

    Linux內(nèi)核中的C語言語法擴(kuò)展

    收集一些感覺比較好的博客鏈接,方便以后再看Linux 內(nèi)核中的 C 語言語法擴(kuò)展Linux 內(nèi)核驅(qū)動中的指定初始化宏構(gòu)造利器:語句表達(dá)式Linux 內(nèi)核第一container_of零長
    發(fā)表于 12-15 06:04

    請教一下大神內(nèi)核源碼中的containerof該怎樣去實(shí)現(xiàn)呢

    內(nèi)核中源碼是這樣的#define container_of(ptr, type, member) ({\ const typeof( ((type *)0)->member ) *__mptr
    發(fā)表于 05-07 11:00

    RT-Thread中侵入式鏈表的應(yīng)用有哪些呢

    rt_container_of(ptr, type, member)((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))具體的解析參見:list_entry/
    發(fā)表于 12-05 13:59

    Linux內(nèi)核基礎(chǔ)-container_of

    TYPE是某struct的類型,0是一個假想TYPE類型struct,MEMBER是該struct中的一個成員。 由于該struct的基地址為0, MEMBER的地址就是該成員相對與struct頭地址的偏移量。
    發(fā)表于 05-14 14:26 ?843次閱讀

    Accelerated Container Image基于塊設(shè)備的容器鏡像加速服務(wù)

    ./oschina_soft/accelerated-container-image.zip
    發(fā)表于 05-10 11:15 ?0次下載
    Accelerated <b class='flag-5'>Container</b> Image基于塊設(shè)備的容器鏡像加速服務(wù)

    container-diff容器鏡像分析對比工具

    ./oschina_soft/container-diff.zip
    發(fā)表于 05-11 10:35 ?0次下載
    <b class='flag-5'>container</b>-diff容器鏡像分析對比工具

    Ansible Container容器自動化構(gòu)建部署工具

    ./oschina_soft/ansible-container.zip
    發(fā)表于 05-11 10:15 ?1次下載
    Ansible <b class='flag-5'>Container</b>容器自動化構(gòu)建部署工具

    Missing Container Metrics容器指標(biāo)收集工具

    ./oschina_soft/missing-container-metrics.zip
    發(fā)表于 05-12 14:24 ?1次下載
    Missing <b class='flag-5'>Container</b> Metrics容器指標(biāo)收集工具

    Linux內(nèi)核中的/container_of分析

    今天在看平臺設(shè)備實(shí)現(xiàn)的時候,看到to_xxx開頭的“函數(shù)”。包括在內(nèi)核中也有很多此類的“函數(shù)”,其實(shí)他們都是container_of。因?yàn)閮?nèi)核是鏈表和結(jié)構(gòu)體的世界,因此內(nèi)核中有大量需求要 根據(jù)結(jié)構(gòu)體成員獲取結(jié)構(gòu)體地址 ,或者根據(jù)結(jié)構(gòu)體類型和結(jié)構(gòu)體成員類型獲取成員在結(jié)構(gòu)
    發(fā)表于 06-23 14:26 ?446次閱讀
    Linux內(nèi)核中的<b class='flag-5'>宏</b>/<b class='flag-5'>container_of</b>分析
    网上百家乐官网是真的| 游戏百家乐官网押金| 24山72向吉凶断| 老虎机定位器| 百家乐官网散台| 百家乐稳赢战术技巧| 大兴区| 天地人百家乐现金网| 博彩旅游业| 乐天百家乐官网的玩法技巧和规则 | 真钱百家乐官网游戏排行| 百家乐时时彩网站| 顶尖娱乐| 百家乐揽子打法| 达州市| 职业赌百家乐技巧| 百家乐官网庄闲的分布| 百家乐追注法| 威尼斯人娱乐城骰宝| 新加坡百家乐官网赌法| 威尼斯人娱乐的微博| 粤港澳百家乐官网娱乐网| 大发888官方网| 海尔百家乐官网的玩法技巧和规则| 大发888娱乐城 下载| 做生意的风水摆件| 贡觉县| 中华百家乐娱乐城| 百家乐官网概率统计| 大发888游戏平台下载| rmb百家乐官网的玩法技巧和规则 木星百家乐官网的玩法技巧和规则 | 威尼斯人娱乐网赌| 百家乐官网一起多少张牌| 真钱的棋牌游戏网站| 百家乐有秘技吗| 网上百家乐官网骗人不| 百家乐游戏打水| 百家乐官网电子发牌盒| 盈丰娱乐城| 找查百家乐玩法技巧| 在线百家乐官网纸牌|