Linux 內核中用C來實現面向對象

1. 就目前的linux內核代碼中,驅動程序 這塊可以說是用C語言進行面向對象編程的一個很好的例子,另外還有一個例子是文件系統部分
驅動這塊的佈局是:
struct usb_interface 包含一個struct device,而struct device包含一個struct kobject結構,struct kobject又包含struct kref。
需要說明的是:(1)kobject 結構體是用來統一的顯示不同的設備 ,以及和這些設備相聯繫的虛擬文件系統 ,這個結構僅具有非常基礎的功能,包括引用計數,被插入到對象層次結構中。
(2)kref是一個只有一個成員: atomic_t refcount; 的結構。 他主要是考慮到:多線程程序設計中,每個開發者爲了管理內存,都需要在結構中加入引用計數,因此,就單獨抽出來。
所以這裏用到的從基類到子類的順序爲:
struct kref -> struct kobject -> struct device -> struct usb_interface

這個例子就是c中的繼承,它利用了結構體之間的組合關係。

 

2. 用C實現面向對象,子類中包含有基類,因此知道了子類很容易就可以獲得基類的信息;但是,如果已知子類中的基類,能不能反查找不它所在的基類的信息呢? 答案是可以,在linux內核中,是使用一個宏來做這個事情的:
#define container_of ( ptr , type, member)  ( {  /
const typeof (  ( (type *) 0 ) -> member ) * _mptr = (ptr); /
(type * ) ( (char *) _mptr  - offsetof (type, member) ) ; /
})
這裏: (1) 顯然offsetof這個編譯器宏仍然可以用 (type*)0->member這樣的方法取代,或者說是實現
(2) 要看清楚,最後那裏是 相減 獲得該子類結構的起始地址!
該宏的一個調用例子爲:
int probe (struct device* d )
{
struct usb_interface *intf;
intf = container_of ( d, struct usb_interface , dev);

//解析一下上面那個宏,就是:

const struct device* _mptr = d;

intf = (struct usb_interface*)( (char*)_mptr - offset(type,member) );

 

#define offset(type,member)  (size_t)&(((type*)0)->member)

 

// dev 是 struct usb_interface中的一個成員名稱,該成員的類型是strcut device;
...
}
}


(附: tree這個命令是以樹的形式顯示,文件夾下的所有文件,包括子目錄的方式~
非常的實用!)

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章