aboutsummaryrefslogtreecommitdiff
path: root/zh_CN.GB2312/books/arch-handbook/kobj/chapter.xml
diff options
context:
space:
mode:
Diffstat (limited to 'zh_CN.GB2312/books/arch-handbook/kobj/chapter.xml')
-rw-r--r--zh_CN.GB2312/books/arch-handbook/kobj/chapter.xml284
1 files changed, 0 insertions, 284 deletions
diff --git a/zh_CN.GB2312/books/arch-handbook/kobj/chapter.xml b/zh_CN.GB2312/books/arch-handbook/kobj/chapter.xml
deleted file mode 100644
index b5799936a0..0000000000
--- a/zh_CN.GB2312/books/arch-handbook/kobj/chapter.xml
+++ /dev/null
@@ -1,284 +0,0 @@
-<?xml version="1.0" encoding="gb2312"?>
-<!--
- The FreeBSD Documentation Project
- The FreeBSD Simplified Chinese Project
-
- Original Revision: 1.7
- $FreeBSD$
--->
-<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="kernel-objects">
- <info><title>内核对象</title>
- <authorgroup>
- <author><personname/><contrib>&cnproj.translated.by;</contrib></author>
- </authorgroup>
- </info>
-
-
- <indexterm><primary>Kernel Objects(内核对象)</primary></indexterm>
- <indexterm><primary>Object-Oriented(面向对象)</primary></indexterm>
- <indexterm><primary>binary compatibility(二进制兼容性)</primary></indexterm>
- <para>内核对象,也就是<firstterm>Kobj</firstterm>,为内核提供了一种面向对象
- 的C语言编程方式。被操作的数据也承载操作它的方法。
- 这使得在不破坏二进制兼容性的前提下,某一个接口能够增/减相应的操作。</para>
-
- <sect1 xml:id="kernel-objects-term">
- <title>术语</title>
-
- <indexterm><primary>object(对象)</primary></indexterm>
- <indexterm><primary>method(方法)</primary></indexterm>
- <indexterm><primary>class(类)</primary></indexterm>
- <indexterm><primary>interface(接口)</primary></indexterm>
-
- <variablelist>
- <varlistentry>
- <term>对象</term>
- <listitem><para>数据集合-数据结构-数据分配的集合</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>方法</term>
- <listitem>
- <para>某一种操作&mdash;函数</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>类</term>
- <listitem>
- <para>一种或多种方法</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>接口</term>
- <listitem>
- <para>一种或多种方法的一个标准集合</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </sect1>
-
- <sect1 xml:id="kernel-objects-operation">
- <title>Kobj的工作流程</title>
-
- <tip><title>译者注</title><para>这一小节两段落中原作者的用词有些含混,
- 请参考我在括号中的注释阅读。</para></tip>
-
- <para>Kobj工作时,产生方法的描述。每个描述有一个唯一的标识和一个缺省函数。
- 某个描述的地址被用来在一个类的方法表里唯一的标识方法。</para>
-
- <para>构建一个类,就是要建立一张方法表,并将这张表关联到一个或多个函数(方法);
- 这些函数(方法)都带有方法描述。使用前,类要被编译。编译时要为这个类分配一些缓存。
- 在方法表中的每个方法描述都会被指派一个唯一的标识,
- 除非已经被其它引用它的类在编译时指派了标识。对于每个将要被使用的方法,
- 都会由脚本生成一个函数(方法查找函数),以解析外来参数,
- 并在被查询时给出方法描述的地址。被生成的函数(方法查找函数)
- 凭着那个方法描述的唯一标识按Hash的方法查找对象的类的缓存。
- 如果这个方法不在缓存中,函数会查找使用类的方法表。如果这个方法被找到了,
- 类里的相关函数(也就是某个方法的实现代码)就会被使用。
- 否则,这个方法描述的缺省函数将被使用。</para>
-
- <para>这些过程可被表示如下:</para>
-
- <programlisting>对象-&gt;缓存&lt;-&gt;类</programlisting>
-
- </sect1>
-
- <sect1 xml:id="kernel-objects-using">
- <title>使用Kobj</title>
-
- <sect2>
- <title>结构</title>
-
- <programlisting>struct kobj_method</programlisting>
- </sect2>
-
- <sect2>
- <title>函数</title>
-
- <programlisting>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);</programlisting>
- </sect2>
-
- <sect2>
- <title>宏</title>
-
- <programlisting>KOBJ_CLASS_FIELDS
-KOBJ_FIELDS
-DEFINE_CLASS(name, methods, size)
-KOBJMETHOD(NAME, FUNC)</programlisting>
- </sect2>
-
- <sect2>
- <title>头文件</title>
-
- <programlisting>&lt;sys/param.h&gt;
-&lt;sys/kobj.h&gt;</programlisting>
- </sect2>
-
- <sect2>
- <title>建立一个接口的模板</title>
-
- <indexterm><primary>Kernel Objects(内核对象)</primary>
- <secondary>interface(接口)</secondary></indexterm>
-
- <para>使用Kobj的第一步是建立一个接口。建立接口包括建立模板的工作。
- 建立模板可用脚本<filename>src/sys/kern/makeobjops.pl</filename>完成,
- 它会产生申明方法的头文件和代码,脚本还会生成方法查找函数。</para>
-
- <para>在这个模板中如下关键词会被使用:
- <literal>#include</literal>, <literal>INTERFACE</literal>,
- <literal>CODE</literal>, <literal>METHOD</literal>,
- <literal>STATICMETHOD</literal>, 和
- <literal>DEFAULT</literal>.</para>
-
- <para><literal>#include</literal>语句的整行内容将被一字不差的
- 复制到被生成的代码文件的头部。</para>
-
- <para>例如:</para>
-
- <programlisting>#include &lt;sys/foo.h&gt;</programlisting>
-
- <para>关键词<literal>INTERFACE</literal>用来定义接口名。
- 这个名字将与每个方法名接合在一起,形成 [interface name]_[method name]。
- 语法是:INTERFACE [接口名];</para>
-
- <para>例如:</para>
-
- <programlisting>INTERFACE foo;</programlisting>
-
- <para>关键词<literal>CODE</literal>会将它的参数一字不差的复制到代码文件中。
- 语法是<literal>CODE { [任何代码] };</literal></para>
-
- <para>例如:</para>
-
- <programlisting>CODE {
- struct foo * foo_alloc_null(struct bar *)
- {
- return NULL;
-}
-};</programlisting>
-
- <para>关键词<literal>METHOD</literal>用来描述一个方法。语法是:
- <literal>METHOD [返回值类型] [方法名] { [对象 [,
- 参数若干]] };</literal></para>
-
- <para>例如:</para>
-
- <programlisting>METHOD int bar {
- struct object *;
- struct foo *;
- struct bar;
-};</programlisting>
-
- <para>关键词<literal>DEFAULT</literal>跟在关键词<literal>METHOD</literal>之后,
- 是对关键词<literal>METHOD</literal>的补充。它给这个方法补充上缺省函数。语法是:
- <literal>METHOD [返回值类型] [方法名] {
- [对象; [其它参数]] }DEFAULT [缺省函数];
- </literal></para>
-
- <para>例如:</para>
-
- <programlisting>METHOD int bar {
- struct object *;
- struct foo *;
- int bar;
-} DEFAULT foo_hack;</programlisting>
-
- <para>关键词<literal>STATICMETHOD</literal>类似关键词<literal>METHOD</literal>。
- 对于每个Kobj对象,一般其头部都有一些Kobj专有的数据。
- <literal>METHOD</literal>定义的方法就假设这些专有数据位于对象头部;
- 假如对象头部没有这些专有数据,这些方法对这个对象的访问就可能出错。
- 而<literal>STATICMETHOD</literal>定义的对象可以不受这个限制:
- 这样描述出的方法,其操作的数据不由这个类的某个对象实例给出,
- 而是全都由调用这个方法时的操作数(译者注:即参数)给出。
- 这也对于在某个类的方法表之外调用这个方法有用。
- <tip><title>译者注</title><para>这一段的语言与原文相比调整很大。
- 静态方法是不依赖于对象实例的方法。
- 参看C++类中的“静态函数”的概念。</para></tip></para>
-
- <para>其它完整的例子:</para>
-
- <programlisting>src/sys/kern/bus_if.m
-src/sys/kern/device_if.m</programlisting>
-
- </sect2>
-
- <sect2>
- <title>建立一个类</title>
-
- <indexterm><primary>Kernel Objects(内核对象)</primary>
- <secondary>class(类)</secondary></indexterm>
-
- <para>使用Kobj的第二步是建立一个类。一个类的组有名字、方法表;
- 假如使用了Kobj的“对象管理工具”(Object Handling Facilities),
- 类中还包含对象的大小。建立类时使用宏<function>DEFINE_CLASS()</function>。
- 建立方法表时,须建立一个kobj_method_t数组,用NULL项结尾。
- 每个非NULL项可用宏<function>KOBJMETHOD()</function>建立。</para>
-
- <para>例如:</para>
-
- <programlisting>DEFINE_CLASS(fooclass, foomethods, sizeof(struct foodata));
-
-kobj_method_t foomethods[] = {
- KOBJMETHOD(bar_doo, foo_doo),
- KOBJMETHOD(bar_foo, foo_foo),
- { NULL, NULL}
-};</programlisting>
-
- <para>类须被<quote>编译</quote>。根据该类被初始化时系统的状态,
- 将要用到一个静态分配的缓存和<quote>操作数表</quote>(ops table,
- 译者注:即<quote>参数表</quote>)。这些操作可通过声明一个结构体
- <varname remap="structname">struct kobj_ops</varname>并使用
- <function>kobj_class_compile_static()</function>,
- 或是只使用<function>kobj_class_compile()</function>来完成。</para>
- </sect2>
-
- <sect2>
- <title>建立一个对象</title>
-
- <indexterm><primary>Kernel Objects(内核对象)</primary>
- <secondary>object(对象)</secondary></indexterm>
-
- <para>使用Kobj的第三步是定义对象。Kobj对象建立程序假定Kobj
- 专有数据在一个对象的头部。如果不是如此,应当先自行分配对象,
- 再使用<function>kobj_init()</function>初始化对象中的Kobj专有数据;
- 其实可以使用<function>kobj_create()</function>分配对象,
- 并自动初始化对象中的Kobj专有内容。<function>kobj_init()</function>
- 也可以用来改变一个对象所使用的类。</para>
-
- <para>将Kobj的数据集成到对象中要使用宏KOBJ_FIELDS。</para>
-
- <para>例如</para>
-
- <programlisting>struct foo_data {
- KOBJ_FIELDS;
- foo_foo;
- foo_bar;
-};</programlisting>
- </sect2>
-
- <sect2>
- <title>调用方法</title>
-
- <para>使用Kobj的最后一部就是通过生成的函数调用对象类中的方法。
- 调用时,接口名与方法名用'_'接合,而且全部使用大写字母。</para>
-
- <para>例如,接口名为foo,方法为bar,调用就是:</para>
-
- <programlisting>[返回值 = ] FOO_BAR(对象 [, 其它参数]);</programlisting>
-
- </sect2>
-
- <sect2>
- <title>善后处理</title>
-
- <para>当一个用<function>kobj_create()</function>不再需要被使用时,
- 可对这个对象调用<function>kobj_delete()</function>。
- 当一个类不再需要被使用时,
- 可对这个类调用<function>kobj_class_free()</function>。</para>
- </sect2>
- </sect1>
-</chapter>