欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Linux內(nèi)核中的container_of函數(shù)

 更新時(shí)間:2016年08月29日 09:47:58   投稿:daisy  
大家都知道Container_of在Linux內(nèi)核中是一個(gè)常用的宏,用于從包含在某個(gè)結(jié)構(gòu)中的指針獲得結(jié)構(gòu)本身的指針,通俗地講就是通過(guò)結(jié)構(gòu)體變量中某個(gè)成員的首地址進(jìn)而獲得整個(gè)結(jié)構(gòu)體變量的首地址。這篇文章詳細(xì)的介紹了Container_of,有需要的可以參考學(xué)習(xí)。

前言

在linux 內(nèi)核中,container_of 函數(shù)使用非常廣,例如 linux內(nèi)核鏈表 list_head、工作隊(duì)列work_struct中。

在linux內(nèi)核中大名鼎鼎的宏container_of() ,其實(shí)它的語(yǔ)法很簡(jiǎn)單,只是一些指針的靈活應(yīng)用,它分兩步:

      第一步,首先定義一個(gè)臨時(shí)的數(shù)據(jù)類型(通過(guò)typeof( ((type *)0)->member )獲得)與ptr相同的指針變量__mptr,然后用它來(lái)保存ptr的值。

      第二步,用(char *)__mptr減去member在結(jié)構(gòu)體中的偏移量,得到的值就是整個(gè)結(jié)構(gòu)體變量的首地址(整個(gè)宏的返回值就是這個(gè)首地址)。

那這個(gè)宏到底是用來(lái)干嘛的呢?我們先來(lái)看看它在內(nèi)核中是怎樣定義的。

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

我們先來(lái)分析一下container_of(ptr,type,member) ,這里面有ptr,type,member分別代表指針、類型、成員。

看一個(gè)例子:

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

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

現(xiàn)在我們知道container_of()的作用就是通過(guò)一個(gè)結(jié)構(gòu)變量中一個(gè)成員的地址找到這個(gè)結(jié)構(gòu)體變量的首地址。

下面來(lái)看看比較復(fù)雜的內(nèi)容:

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

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

其中,typeof是GNU C對(duì)標(biāo)準(zhǔn)C的擴(kuò)展,它的作用是根據(jù)變量獲取變量的類型。因此,上述代碼的作用是首先使用typeof獲取結(jié)構(gòu)體成員j的類型為int,然后頂一個(gè)int指針類型的臨時(shí)變量__mptr,并將結(jié)構(gòu)體變量中的成員的地址賦給臨時(shí)變量__mptr

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

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

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

一開(kāi)始也不明白,這里要感謝曹忠明老師的熱心幫助,一語(yǔ)驚醒夢(mèng)中人,呵呵,可以是這樣理解。

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

程序運(yùn)行結(jié)果:

發(fā)現(xiàn)沒(méi)有如果把第二個(gè)值 減去最后一個(gè)值,就能得到第一個(gè)值。

在回首一下它:

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

是不是可以獲得結(jié)構(gòu)體變量temp的首地址呀,是不是太精妙了呀

總結(jié)

linux內(nèi)核中隨隨便便一個(gè)宏就有如此精妙,想想對(duì)linux了解非常多的牛人,還有很長(zhǎng)一段路。好了,以上就是本文的全部?jī)?nèi)容了,希望這篇文章的內(nèi)容對(duì)大家的工作和學(xué)習(xí)能有所幫助,如果有疑問(wèn)可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

最新評(píng)論