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)头文件
建立一个接口的模板
使用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;
}
};【FreeBSD系统内核对象】关键词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定义的对象可以不受这个限制:这样描述出的方法,其操作的数据不由这个类的某个对象实例给出,而是全都由调用这个方法时的操作数(译者注:即参数)给出 。这也对于在某个类的方法表之外调用这个方法有用 。
其它完整的例子:

推荐阅读