2011-02-28 81 views

回答

5

container_of,可以忽略指向父s到簡化你的數據結構tructures。

它在鏈表實現中使用,以便列表節點可以是任何結構的元素,並且任何人都可以在不帶有顯式指針的情況下找到父結構。

另一個例子是struct work_struct。一個workqueue工作函數接收一個work_struct作爲參數,並且它曾經有一個通用的「數據」有效載荷。該數據值爲removed,使結構更小,因爲工作函數可以調用container_of來查找其父結構。

3

這是一種解決C沒有泛型或模板這一事實的方法。

你想要一個通用的鏈表,所以你只需要把指針放在節點本身(這樣你就可以抽象出結構本身的管理),然後用CONTAINING_RECORD找到你自己代碼中的其餘數據如:

struct Node { struct Node *prev, *next; } 

//Now you can define functions that operate on a generic struct Node* 

struct Item 
{ 
    int myData; 
    struct Node* node; //this would point to the 'node' member of another Item 
} 

現在,給定一個struct Node,你可以找到它的Item說:

CONTAINING_RECORD(ptr, Item, node) 
+0

給定名爲'結構NODE''ptr',我想你的意思是:'CONTAINING_RECORD(PTR,項目,節點)' – 2011-02-28 17:13:29

+0

哎呀呀,謝謝你,我會改變它 – Mehrdad 2011-02-28 17:14:04

+0

不會是CONTAINING_RECORD(ptr,struct Item,node)嗎? – 2012-09-10 14:53:51

0

它將指向結構成員的指針調整爲指向包含結構的指針;這在內核中以各種方式使用,最常見的可以被描述爲具有靜態偏移的向下轉換,其中外部結構是從內部派生(通過包含),並且調用者在內部對象上調用方法,即然後分派給外部對象上的方法。

那麼,沒有來自編譯器的OO支持。

4

對於未來搜索器(R)S:這是我迄今發現的最好的解釋:

http://psomas.wordpress.com/2009/07/01/weird-kernel-macros-container_of/

基本上(報價):

「現在我們可以理解(至少部分)這個宏是做什麼的,它聲明一個指向結構成員ptr指向的指針,並減去它來自struct ‘instance’(ie __mptr)的成員的實際地址。 (char *)__mptr強制轉換是必要的,因此「指針算術」將按預期工作,即從__mptr減去offsetof「返回」的(size_t)字節。「

,並且還另外兩個顯著提示(報價):

」在這一點上,我真的不明白,爲什麼我們不能直接使用PTR指針。我們可以ommit第一線,和宏可能是

#define container_of(ptr, type, member) (type *)((char *)(ptr) - offsetof(type,member)) 

ptr只使用一次 - 我們並不需要擔心的副作用。 也許這只是一個良好的編碼實踐「

,並在原來的職位(報價)的後來編輯:

」。顯然,第一行是有‘類型檢查’。它確保type有一個名爲member的成員(但我認爲這也是由offsetof宏完成的),並且如果ptr不是指向正確類型(member的類型)的指針,編譯器將打印警告, 。這對於調試運行有用」