歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Unix知識 >> Unix教程

FreeBSD系統內核對象

FreeBSD
  內核對象,也就是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)
  
  頭文件
  <SYS param.h>lt;SYS kobj.h>
  
  建立一個接口的模板
  
  使用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()。
Copyright © Linux教程網 All Rights Reserved