c語言中的面向對象(1)----kobject 和 container_of

最近看驅動開發,看linux的device model,有一些感觸。暫記於下。html

我以前一直把OO(object oriented)這個概念和特定的語言聯繫在一塊兒。好比,認爲c++,java,python等是面向對象的語言,C語言就不是。這種想法不太對,並且有時很危險,至少,這樣的想法會限制你解決問題的思路。java

OO和語言應該分開來看。OO是一種解決問題的概念,是對問題的一種抽象;而編程語言,是解決問題的工具。python

如下線簡單談談kobject和container_of.linux

從oo的觀點來看,kobject就是一個super class, 配合container_of這個宏,實現了運行時的動態綁定特性。c++

在kernel中,幾乎全部的device,都會有一個kobject域,好比cdev編程

struct cdev {
    struct kobject kobj;
    struct module *owner;
    struct file_operations *ops;
    struct list_head list;
    dev_t dev;
    unsigned int count;
};編程語言

這個kobject是用來提供一些基礎服務的,如reference counting, data structure glue, hotplug handing等。咱們能夠把這些structure都當作是kobject的派生類。那麼問題就來了,這些派生類會有不少種,而他們的好多操做,從含義上來說,是同樣的,好比create,好比remove等。咱們天然能夠爲每個類定義它對應的操做,這對實現沒有問題。可是,上層調用這些類的時候,面對每個含義類似的操做卻有不一樣的參數類型,會是何等蛋疼的一件事情!!!函數

在c++中,咱們是經過傳遞基類指針或者引用的方式,經過動態綁定來解決這個問題的。工具

可是,c語言沒有內建這種面向對象的機制。它是如何來解決這個問題的呢?指針

今天,簡單隻談一點:container_of

 

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

這個宏的做用是,經過結構的一個域,來取得該結構的指針。

好比有某個kobject* pk指向某個kobject。而此kobject是cdev中一員。能夠用如下語句,取得該cdev結構的指針

container_of(pk, cdev, kobj);

由於全部device structure都包含kobject域,因此,咱們能夠給一些語義想通的操做,傳遞kobject指針,而在函數內部,利用container_of來取得實際的對象的指針,從而進行相應操做。

如下,簡單解析下container_of宏。

其結構是({A;B;})。主要原理是經過指針操做(加減必定的數值)以及強制類型轉換,來返回指向某個內存的一個特定類型的指針。原理比較簡單,有兩點可能會有些疑惑,以下。

1.({A;B;})的含義。 對c和c++熟悉的人應該知道,它返回的值是B表達式的值。懷疑的能夠試一下printf("%d", ({1;2;3;});

2.typeof的含義。typeof是c新引進的關鍵詞。參考以下鏈接。typeof的實現方法想來比較簡單,就是在稍微改下編譯器的實現就ok了。在編譯器關鍵詞中天劍typeof,而後進行語法處理的時候對typeof的表達式進行分析求值。

http://gcc.gnu.org/onlinedocs/gcc/Typeof.html

相關文章
相關標籤/搜索