FreeBSD系統核心物件(轉)

BSDLite發表於2007-08-12
FreeBSD系統核心物件(轉)[@more@]核心物件,也就是Kobj,為作業系統核心提供了一種物件導向的C語言程式設計方式。被操作的資料也承載操作它的方法。這使得在不破壞二進位制相容性的前提下,某一個介面能夠增/減相應的操作。Kobj工作時,產生方法的描述。每個描述有一個唯一的標識和一個預設函式。某個描述的地址被用來在一個類的方法表裡唯一的標識方法。 構建一個類,就是要建立一張方法表,並將這張表關聯到一個或多個函式(方法);這些函式(方法)都帶有方法描述。使用前,類要被編譯。編譯時要為這個類分配一些快取。在方法表中的每個方法描述都會被指派一個唯一的標識,除非已經被其它引用它的類在編譯時指派了標識。對於每個將要被使用的方法,都會由指令碼生成一個函式(方法查詢函式),以解析外來引數,並在被查詢時給出方法描述的地址。被生成的函式(方法查詢函式)憑著那個方法描述的唯一標識按Hash的方法查詢物件的類的快取。如果這個方法不在快取中,函式會查詢使用類的方法表。如果這個方法被找到了,類裡的相關函式(也就是某個方法的實現程式碼)就會被使用。否則,這個方法描述的預設函式將被使用。 這些過程可被表示如下: 物件->快取類

如何使用Kobj
結構
struct kobj_method

函式
void kobj_class_compile(kobj_class_t cls);
void kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops);
void kobj_class_free(kobj_class_t cls);
kobj_t kobj_create(kobj_class_t cls, struct malloc_type *mtype, int mflags);
void kobj_init(kobj_t obj, kobj_class_t cls);
void kobj_delete(kobj_t obj, struct malloc_type *mtype);


KOBJ_CLASS_FIELDS
KOBJ_FIELDS
DEFINE_CLASS(name, methods, size)
KOBJMETHOD(NAME, FUNC)

標頭檔案
建立一個介面的模板

使用Kobj的第一步是建立一個介面。建立介面包括建立模板的工作。建立模板可用指令碼src/sys/kern/makeobjops.pl完成,它會產生申明方法的標頭檔案和程式碼,指令碼還會生成方法查詢函式。 在這個模板中如下關鍵詞會被使用: #include, INTERFACE, CODE, METHOD, STATICMETHOD, 和 DEFAULT. #include語句的整行內容將被一字不差的複製到被生成的程式碼檔案的頭部。

例如: #include 關鍵詞INTERFACE用來定義介面名。這個名字將與每個方法名接合在一起,形成 [interface name]_[method name]。語法是:INTERFACE [介面名]; 例如: INTERFACE foo; 關鍵詞CODE會將它的引數一字不差的複製到程式碼檔案中。語法是CODE { [任何程式碼] }; 例如:
CODE {
struct foo * foo_alloc_null(struct bar *)
{
return NULL;
}
};
關鍵詞METHOD用來描述一個方法。語法是: METHOD [返回值型別] [方法名] { [物件 [, 引數若干]] }; 例如:
METHOD int bar {
struct object *;
struct foo *;
struct bar;
};
關鍵詞DEFAULT跟在關鍵詞METHOD之後,是對關鍵詞METHOD的補充。它給這個方法補充上預設函式。語法是: METHOD [返回值型別] [方法名] { [物件; [其它引數]] }DEFAULT [預設函式]; 例如:
METHOD int bar {
struct object *;
struct foo *;
int bar;
} DEFAULT foo_hack;
關鍵詞STATICMETHOD類似關鍵詞METHOD。對於每個Kobj物件,一般其頭部都有一些Kobj專有的資料。METHOD定義的方法就假設這些專有資料位於物件頭部;假如物件頭部沒有這些專有資料,這些方法對這個物件的訪問就可能出錯。而STATICMETHOD定義的物件可以不受這個限制:這樣描述出的方法,其操作的資料不由這個類的某個物件例項給出,而是全都由呼叫這個方法時的運算元(譯者注:即引數)給出。這也對於在某個類的方法表之外呼叫這個方法有用。

其它完整的例子:
src/sys/kern/bus_if.m
src/sys/kern/device_if.m
建立一個類

使用Kobj的第二步是建立一個類。一個類的組有名字、方法表;假如使用了Kobj的“物件管理工具”(Object Handling Facilities),類中還包含物件的大小。建立類時使用宏DEFINE_CLASS()。建立方法表時,須建立一個kobj_method_t陣列,用NULL項結尾。每個非NULL項可用宏KOBJMETHOD()建立。 例如:
DEFINE_CLASS(fooclass, foomethods, sizeof(struct foodata));

kobj_method_t foomethods[] = {
KOBJMETHOD(bar_doo, foo_doo),
KOBJMETHOD(bar_foo, foo_foo),
{ NULL, NULL}
};
類須被“編譯”。根據該類被初始化時系統的狀態,將要用到一個靜態分配的快取和“運算元表”(ops table,譯者注:即“參數列”)。這些操作可透過宣告一個結構體struct kobj_ops並使用kobj_class_compile_static(),或是隻使用kobj_class_compile()來完成。

建立一個物件

使用Kobj的第三步是定義物件。Kobj物件建立程式假定Kobj專有資料在一個物件的頭部。如果不是如此,應當先自行分配物件,再使用kobj_init()初始化物件中的Kobj專有資料;其實可以使用kobj_create()分配物件,並自動初始化物件中的Kobj專有內容。kobj_init()也可以用來改變一個物件所使用的類。 將Kobj的資料整合到物件中要使用宏KOBJ_FIELDS。 例如:
struct foo_data {
KOBJ_FIELDS;
foo_foo;
foo_bar;
};
呼叫方法

使用Kobj的最後一部就是透過生成的函式呼叫物件類中的方法。呼叫時,介面名與方法名用'_'接合,而且全部使用大寫字母。 例如,介面名為foo,方法為bar,呼叫就是: [返回值 = ] FOO_BAR(物件 [, 其它引數]);

當一個用kobj_create()不再需要被使用時,可對這個物件呼叫kobj_delete()。當一個類不再需要被使用時,可對這個類呼叫kobj_class_free()。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-949292/,如需轉載,請註明出處,否則將追究法律責任。

相關文章