你好,游客 登錄 注冊 搜索
背景:
閱讀新聞

Linux內核中container_of函數詳解

[日期:2016-08-22] 來源:Linux社區  作者:Linux [字體: ]

在Linux 內核中,container_of 函數使用非常廣,例如 Linux內核鏈表 list_head、工作隊列work_struct中。

在Linux 內核中有一個大名鼎鼎的宏container_of(),這個宏是用來干嘛的呢?我們先來看看它在內核中是怎樣定義的。

呵呵,乍一看不知道是什么東東。

我們先來分析一下container_of(ptr,type,member),這里面有ptr,type,member分別代表指針、類型、成員。看一個例子:

Struct test
        {
                int i;
                int j;
                char k;
        };
        Struct test temp;

現在呢如果我想通過temp.j的地址找到temp的首地址就可以使用container_of(&temp.j,struct test,j);

現在我們知道container_of()的作用就是通過一個結構變量中一個成員的地址找到這個結構體變量的首地址。

下面來看看比較復雜的內容:

我們用上面的struct test張展一下

Const typeof(((struct test *)0)->j) * __mptr = (&temp.j);   //(sturct test *)0 表示數據段基址 

其中,typeof是GNU C對標準C的擴展,它的作用是根據變量獲取變量的類型。因此,上述代碼的作用是首先使用typeof獲取結構體成員j的類型為int,然后頂一個int指針類型的臨時變量__mptr,并將結構體變量中的成員的地址賦給臨時變量__mptr。

(struct test *)((char *)__mptr - offsetof(struct test,j));

接著我們來看一下offsetof(struct test,j),他在內核中如下定義

展開(size_t)&((struct test *)0)->j,這是什么東東?

一開始也不明白,這里要感謝曹忠明老師的熱心幫助,一語驚醒夢中人,呵呵,可以是這樣理解。

其中size_t是整型,那么我們可以知道最終的結果是一個整形值,也就是j相對于0地址的偏移量。也許現在你會問,整出這么個玩意干嘛,下面看個列子:

程序運行結果:

發現沒有如果把第二個值 減去最后一個值,就能得到第一個值。

在回首一下它:

(struct test *)((char *)__mptr - offsetof(struct test,j));

是不是可以獲得結構體變量temp的首地址呀,是不是太精妙了呀,linux內核中隨隨便便一個宏就有如此精妙,呵呵,想想對linux了解非常多的牛人,還有很長一段路。

本文永久更新鏈接地址http://www.nmzech.live/Linux/2016-08/134481.htm

linux
本文評論   查看全部評論 (0)
表情: 表情 姓名: 字數

       

評論聲明
  • 尊重網上道德,遵守中華人民共和國的各項有關法律法規
  • 承擔一切因您的行為而直接或間接導致的民事或刑事法律責任
  • 本站管理人員有權保留或刪除其管轄留言中的任意內容
  • 本站有權在網站內轉載或引用您的評論
  • 參與本評論即表明您已經閱讀并接受上述條款
北京快乐8走势图彩客网