精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

container_of()宏,太妙了~

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

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

該宏的作用是通過結構體成員的地址和結構體類型推導出結構體的地址,type是指結構體的類型,member是成員在結構體中的名字,ptr是該成員在type結構體中的地址。

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() 初學者可能會對其很陌生,所以我們要先從理解 offsetof(TYPE, MEMBER)typeof() 的作用開始。

offsetof(TYPE, MEMBER)

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

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

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

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

實例:

#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實例結果輸出

typeof()

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

#include

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


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

return0;
}

輸出:

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

img

container_of(ptr, type, member)

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

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

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

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

該代碼是將獲取的 MEMBER 成員地址強轉為 char *(強轉的目的是考慮指針的加減的實質是指針在內存的偏移,偏移量為指針類型所占字節的個數),減去 MEMBER 成員在 type 結構體中的偏移量,強轉為 type * 后得到結構體的地址。實例:

#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在實例結構體中的地址結構體類型成員名*/
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


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11229

    瀏覽量

    208928
  • 源碼
    +關注

    關注

    8

    文章

    633

    瀏覽量

    29140
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    10833

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

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

收藏 人收藏

    評論

    相關推薦

    Linux內核中container_of原理詳解

    Linux內核中經常可見container_of的身影,它在實際驅動的編寫中也是廣泛應用。
    發表于 07-14 15:19 ?301次閱讀
    Linux內核中<b class='flag-5'>container_of</b>原理詳解

    詳細聊聊container_of這個定義

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

    揭開linux內核中container_of的神秘面紗

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

    offsetofcontainer_of詳解

    offsetofcontainer_of詳解 1.offsetofcontainer_of
    發表于 10-13 16:35

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

    使用Labview active container引用后,單個VI運行是正常的,單將單個VI引入后,出現異常,這種問題需要怎樣解決,有相關經驗的人沒。
    發表于 05-19 18:31

    鴻蒙應用開發-container動漫效果體驗

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

    Linux內核中的C語言語法擴展

    收集一些感覺比較好的博客鏈接,方便以后再看Linux 內核中的 C 語言語法擴展Linux 內核驅動中的指定初始化宏構造利器:語句表達式Linux 內核第一container_of零長
    發表于 12-15 06:04

    請教一下大神內核源碼中的containerof該怎樣去實現呢

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

    RT-Thread中侵入式鏈表的應用有哪些呢

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

    Linux內核基礎-container_of

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

    Accelerated Container Image基于塊設備的容器鏡像加速服務

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

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

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

    Ansible Container容器自動化構建部署工具

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

    Missing Container Metrics容器指標收集工具

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

    Linux內核中的/container_of分析

    今天在看平臺設備實現的時候,看到to_xxx開頭的“函數”。包括在內核中也有很多此類的“函數”,其實他們都是container_of。因為內核是鏈表和結構體的世界,因此內核中有大量需求要 根據結構體成員獲取結構體地址 ,或者根據結構體類型和結構體成員類型獲取成員在結構
    發表于 06-23 14:26 ?374次閱讀
    Linux內核中的<b class='flag-5'>宏</b>/<b class='flag-5'>container_of</b>分析