linux 內(nèi)核 container_of() 宏函數(shù) 原理詳解

container_of() 宏函數(shù)源碼:

/**

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

* @ptr: the pointer to the member.

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

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

*/

#define container_of(ptr, type, member) ({ \

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

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



函數(shù)作用:

??????????????????????????????? 根據(jù)某結(jié)構(gòu)體任意一個(gè)成員首地址,獲得整個(gè)結(jié)構(gòu)體變量的首地址。

原理:

??????????????????????????????? 某結(jié)構(gòu)體的任意一個(gè)成員的相對(duì)地址 減去 該成員在該結(jié)構(gòu)體中的絕對(duì)偏移 就是該結(jié)構(gòu)體的相對(duì)首地址

實(shí)例:

??????????????????????????????? struct TEST

????????????????????????????????? {

???????????????????????????????????????????? int a;

???????????????????????????????????????????? char b;

???????????????????????????????????????????? float c;

??????????????????????????????????? };

該結(jié)構(gòu)體的內(nèi)存分配如下圖:

?

struct TEST mTEST={10,'F',12.12};

char *pB=&mTEST.b;

假如pB地址等于0xAABBCC04,根據(jù)內(nèi)存分配推斷mTEST的首地址應(yīng)該為:0xAABBCC00

那么container_of()如何根據(jù)pB變量獲得mTEST的首地址呢?

步驟如下:

1.利用GNU C標(biāo)準(zhǔn)中的 typeof 關(guān)鍵字,根據(jù)結(jié)構(gòu)體struct TEST的成員b,定義一個(gè)和b同類型的臨時(shí)變量指針用來(lái)存儲(chǔ)輸入ptr.

const typeof( ((struct TEST *)0)->b ) *__mptr = (ptr);

2.利用offsetof()獲得成員變量b在結(jié)構(gòu)體struct TEST中的絕對(duì)偏移量=4,而__mptr=0xAABBCC04,所以獲得mTEST的首地址=0xAABBCC00

? 和推斷一樣。為什么用(char *)強(qiáng)制類型轉(zhuǎn)換__mptr,是為了讓指針__mptr按一個(gè)字節(jié)一個(gè)字節(jié)偏移,要不然會(huì)根據(jù)__mptr數(shù)據(jù)類型進(jìn)行偏

?? 移,算出來(lái)的地址就不對(duì)了。

(struct TEST *)( (char *)__mptr - offsetof(struct TEST,b) );

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容