ptr:指向例項化的結構體元素member的指標
type:是這個結構體型別
member:結構體中乙個元素的元素名
(1) ((type *)0)->member 將0位址定義成乙個type型別指標,這個指標就可以訪問這個型別裡面的任意元素了
(2) typeof(((type *)0)->member) 得到這個元素的資料型別
(3) const typeof(((type *)0)->member) * __mptr = (ptr) 把記憶體中被例項化的結構體變數裡面member元素的指標用新定義的__mptr存下來,__mptr就是member元素的指標型別
(4) offsetof(type, member) 得到type結構體中某個元素和結構體首位址的偏移量(所以的位址含義都是以位元組位單位的,因為記憶體就是這樣定義的比如0000到0001就是乙個位元組)
(5) (char *)__mptr - offsetof(type, member) __mptr本身是乙個指標,它裡面的值就是指向的元素的位址比如 p = p1;p1 = &b;p存的就是b的位址,(char *)p後,相當於p是乙個指向char的指標,p+1時,位址才會加1,要看p指向的型別,覺得p+1等於多少,這時與偏移量相減值才對
(6)(type *)((char *)__mptr - offsetof(type, member)) 將指標變成指向結構體型別的指標
(1)比如核心管理驅動,假設乙個結構體a包含整個驅動所以資訊(在記憶體中被例項化,由malloc申請得到的位址空間),裡面有乙個b結構體是這個驅動某一類的資訊,b裡面包含乙個雙向鍊錶節點,核心每註冊和解除安裝乙個驅動,這個管理驅動的雙向鍊錶裡面對應的就會新增和刪除乙個節點,我們可以很容易得到這個鍊錶節點的指標,然後利用b裡面這個成員指標,得到結構體變數b的指標,再得到變數a的指標(也就是得到乙個指向a結構體的指標),通過這個指標去操作a裡面的每個元素
(2)一般地,在應用程式設計中,已知a結構體變數裡面的某個成員的指標,想去知道其他成員的指標或者變數。首先我們知道某個成員b的指標,container_of得到整個結構體變數的指標,然後定義乙個該型別的指標p,去接受container_of返回的指標,去指向a裡面任意乙個元素,就得到了這個元素,然後對這個元素賦值
(3)本來可以通過a結構體變數取位址得到&a,就能得到a的指標,但是在核心裡面我們有時候無法訪問到結構體變數a,無法得到&a,核心在對結構體a進行填充時,是在多個函式裡面分別對a的某一部分進行填充,這些函式接收的引數是a裡面某個元素的指標,我估計,比如有時候我們通過驅動的id來記錄是哪個驅動,核心返回乙個id給我們,這個id就是a結構體裡面的乙個元素,這個時候我們無法得知這個id所在的結構體變數名,所以無法&a,然後在另乙個函式c裡面要操作這個結構體裡面其他元素,這時只能傳&id給函式c,內部通過container_of得到整個結構體a的指標,再去操作其他元素
container of巨集定義
1 container of在linux核心中是乙個常用的巨集,用於從包含在某個結構中的指標獲得結構本身的指標,通俗地講就是通過結構體變數中某個成員的首位址進而獲得整個結構體變數的首位址。2 介面 container of ptr,type,member ptr 表示結構體中member的位址 ty...
container of巨集詳解
該巨集位於include linux kernel.h 1.定義格式 define container of ptr,type,member 作用 就是根據乙個結構體變數中的乙個域成員變數的指標來獲取指向整個結構體變數的指標。例 struct demo struct struct demo stru...
Linux 核心巨集 container of
container of ptr,type,member arguments ptrthe pointer to the member.代表指標 type the type ofthe container struct this isembedded in.型別 member 成員變數 the na...