Add a chapter on Kernel Objects. The content is rather limited right
now but there are several other texts that can be integrated into this chapter. PR: 27678 Submitted by: Jason Smethers <jason@smethers.net>
This commit is contained in:
parent
598555cf3f
commit
32c554e9bb
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=10527
6 changed files with 604 additions and 4 deletions
en_US.ISO8859-1/books
arch-handbook
developers-handbook
|
@ -1,7 +1,7 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/book.sgml,v 1.24 2001/07/22 14:00:50 asmodai Exp $
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/book.sgml,v 1.25 2001/08/16 03:34:59 dd Exp $
|
||||
-->
|
||||
|
||||
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
|
||||
|
@ -87,6 +87,7 @@
|
|||
</chapter>
|
||||
|
||||
&chap.locking;
|
||||
&chap.kobj;
|
||||
&chap.vm;
|
||||
&chap.dma;
|
||||
&chap.kerneldebug;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
Chapters should be listed in the order in which they are referenced.
|
||||
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/chapters.ent,v 1.9 2001/06/23 04:57:32 murray Exp $
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/chapters.ent,v 1.10 2001/07/19 22:06:06 murray Exp $
|
||||
-->
|
||||
|
||||
<!-- Part one -->
|
||||
|
@ -15,6 +15,7 @@
|
|||
<!ENTITY chap.secure SYSTEM "secure/chapter.sgml">
|
||||
|
||||
<!-- Part two -->
|
||||
<!ENTITY chap.kobj SYSTEM "kobj/chapter.sgml">
|
||||
<!ENTITY chap.locking SYSTEM "locking/chapter.sgml">
|
||||
|
||||
<!-- Part three -->
|
||||
|
|
298
en_US.ISO8859-1/books/arch-handbook/kobj/chapter.sgml
Normal file
298
en_US.ISO8859-1/books/arch-handbook/kobj/chapter.sgml
Normal file
|
@ -0,0 +1,298 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
<chapter id="kernel-objects">
|
||||
<title>Kernel Objects</title>
|
||||
|
||||
<para>Kernel Objects, or <firstterm>Kobj</firstterm> provides an
|
||||
object-oriented C programming system for the kernel. As such the
|
||||
data being operated on carries the description of how to operate
|
||||
on it. This allows operations to be added and removed from an
|
||||
interface at run time and without breaking binary
|
||||
compatibility.</para>
|
||||
|
||||
<sect1>
|
||||
<title>Terminology</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Object</term>
|
||||
<listitem><para>A set of data - data structure - data
|
||||
allocation.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Method</term>
|
||||
<listitem>
|
||||
<para>An operation - function.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Class</term>
|
||||
<listitem>
|
||||
<para>One or more methods.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Interface</term>
|
||||
<listitem>
|
||||
<para>A standard set of one or more methods.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Kobj Operation</title>
|
||||
|
||||
<para>Kobj works by generating descriptions of methods. Each
|
||||
description holds a unique id as well as a default function. The
|
||||
description's address is used to uniquely identify the method
|
||||
within a class' method table.</para>
|
||||
|
||||
<para>A class is built by creating a method table associating one
|
||||
or more functions with method descriptions. Before use the class
|
||||
is compiled. The compilation allocates a cache and associates it
|
||||
with the class. A unique id is assigned to each method
|
||||
description within the method table of the class if not already
|
||||
done so by another referencing class compilation. For every
|
||||
method to be used a function is generated by script to qualify
|
||||
arguments and automatically reference the method description for
|
||||
a lookup. The generated function looks up the method by using
|
||||
the unique id associated with the method description as a hash
|
||||
into the cache associated with the object's class. If the method
|
||||
is not cached the generated function proceeds to use the class'
|
||||
table to find the method. If the method is found then the
|
||||
associated function within the class is used; otherwise, the
|
||||
default function associated with the method description is
|
||||
used.</para>
|
||||
|
||||
<para>These indirections can be visualized as the
|
||||
following:</para>
|
||||
|
||||
<programlisting>object->cache<->class</programlisting>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Using Kobj</title>
|
||||
|
||||
<sect2>
|
||||
<title>Structures</title>
|
||||
|
||||
<programlisting>struct kobj_method</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Functions</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>Macros</title>
|
||||
|
||||
<programlisting>KOBJ_CLASS_FIELDS
|
||||
KOBJ_FIELDS
|
||||
DEFINE_CLASS(name, methods, size)
|
||||
KOBJMETHOD(NAME, FUNC)</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Headers</title>
|
||||
|
||||
<programlisting><sys/param.h>
|
||||
<sys/kobj.h></programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Creating an interface template</title>
|
||||
|
||||
<para>The first step in using Kobj is to create an
|
||||
Interface. Creating the interface involves creating a template
|
||||
that the script
|
||||
<filename>src/sys/kern/makeobjops.pl</filename> can use to
|
||||
generate the header and code for the method declarations and
|
||||
method lookup functions.</para>
|
||||
|
||||
<para>Within this template the following keywords are used:
|
||||
<literal>#include</literal>, <literal>INTERFACE</literal>,
|
||||
<literal>CODE</literal>, <literal>METHOD</literal>,
|
||||
<literal>STATICMETHOD</literal>, and
|
||||
<literal>DEFAULT</literal>.</para>
|
||||
|
||||
<para>The <literal>#include</literal> statement and what follows
|
||||
it is copied verbatim to the head of the generated code
|
||||
file.</para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>#include <sys/foo.h></programlisting>
|
||||
|
||||
<para>The <literal>INTERFACE</literal> keyword is used to define
|
||||
the interface name. This name is concatenated with each method
|
||||
name as [interface name]_[method name]. It's syntax is
|
||||
INTERFACE [interface name];.</para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>INTERFACE foo;</programlisting>
|
||||
|
||||
<para>The <literal>CODE</literal> keyword copies its arguments
|
||||
verbatim into the code file. It's syntax is
|
||||
<literal>CODE { [whatever] };</literal></para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>CODE {
|
||||
struct foo * foo_alloc_null(struct bar *)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
};</programlisting>
|
||||
|
||||
<para>The <literal>METHOD</literal> keyword describes a method. It's syntax is
|
||||
<literal>METHOD [return type] [method name] { [object [,
|
||||
arguments]] };</literal></para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>METHOD int bar {
|
||||
struct object *;
|
||||
struct foo *;
|
||||
struct bar;
|
||||
};</programlisting>
|
||||
|
||||
<para>The <literal>DEFAULT</literal> keyword may follow the
|
||||
<literal>METHOD</literal> keyword. It extends the
|
||||
<literal>METHOD</literal> key word to include the default
|
||||
function for method. The extended syntax is
|
||||
<literal>METHOD [return type] [method name] {
|
||||
[object; [other arguments]] }DEFAULT [default
|
||||
function];</literal></para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>METHOD int bar {
|
||||
struct object *;
|
||||
struct foo *;
|
||||
int bar;
|
||||
} DEFAULT foo_hack;</programlisting>
|
||||
|
||||
<para>The <literal>STATICMETHOD</literal> keyword is used like
|
||||
the <literal>METHOD</literal> keyword except the kobj data isn't
|
||||
at the head of the object structure so casting to kobj_t would
|
||||
be incorrect. Instead <literal>STATICMETHOD</literal> relies on the Kobj data being
|
||||
referenced as 'ops'. This is also useful for calling
|
||||
methods directly out of a class's method table.</para>
|
||||
|
||||
<para>Other complete examples:</para>
|
||||
|
||||
<programlisting>src/sys/kern/bus_if.m
|
||||
src/sys/kern/device_if.m</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Creating a Class</title>
|
||||
|
||||
<para>The second step in using Kobj is to create a class. A
|
||||
class consists of a name, a table of methods, and the size of
|
||||
objects if Kobj's object handling facilities are used. To
|
||||
create the class use the macro
|
||||
<function>DEFINE_CLASS()</function>. To create the method
|
||||
table create an array of kobj_method_t terminated by a NULL
|
||||
entry. Each non-NULL entry may be created using the macro
|
||||
<function>KOBJMETHOD()</function>.</para>
|
||||
|
||||
<para>For example:</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>The class must be <quote>compiled</quote>. Depending on
|
||||
the state of the system at the time that the class is to be
|
||||
initialized a statically allocated cache, <quote>ops
|
||||
table</quote> have to be used. This can be accomplished by
|
||||
declaring a <structname>struct kobj_ops</structname> and using
|
||||
<function>kobj_class_compile_static();</function> otherwise,
|
||||
<function>kobj_class_compile()</function> should be used.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Creating an Object</title>
|
||||
|
||||
<para>The third step in using Kobj involves how to define the
|
||||
object. Kobj object creation routines assume that Kobj data is
|
||||
at the head of an object. If this in not appropriate you will
|
||||
have to allocate the object yourself and then use
|
||||
<function>kobj_init()</function> on the Kobj portion of it;
|
||||
otherwise, you may use <function>kobj_create()</function> to
|
||||
allocate and initialize the Kobj portion of the object
|
||||
automatically. <function>kobj_init()</function> may also be
|
||||
used to change the class that an object uses.</para>
|
||||
|
||||
<para>To integrate Kobj into the object you should use the macro
|
||||
KOBJ_FIELDS.</para>
|
||||
|
||||
<para>For example</para>
|
||||
|
||||
<programlisting>struct foo_data {
|
||||
KOBJ_FIELDS;
|
||||
foo_foo;
|
||||
foo_bar;
|
||||
};</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Calling Methods</title>
|
||||
|
||||
<para>The last step in using Kobj is to simply use the generated
|
||||
functions to use the desired method within the object's
|
||||
class. This is as simple as using the interface name and the
|
||||
method name with a few modifications. The interface name
|
||||
should be concatenated with the method name using a '_'
|
||||
between them, all in upper case.</para>
|
||||
|
||||
<para>For example, if the interface name was foo and the method
|
||||
was bar then the call would be:</para>
|
||||
|
||||
<programlisting>[return value = ] FOO_BAR(object [, other parameters]);</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Cleaning Up</title>
|
||||
|
||||
<para>When an object allocated through
|
||||
<function>kobj_create()</function> is no longer needed
|
||||
<function>kobj_delete()</function> may be called on it, and
|
||||
when a class is no longer being used
|
||||
<function>kobj_class_free()</function> may be called on it.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-declaration: "../chapter.decl"
|
||||
sgml-indent-data: t
|
||||
sgml-omittag: nil
|
||||
sgml-always-quote-attributes: t
|
||||
sgml-parent-document: ("../book.sgml" "part" "chapter")
|
||||
End:
|
||||
-->
|
|
@ -1,7 +1,7 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/book.sgml,v 1.24 2001/07/22 14:00:50 asmodai Exp $
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/book.sgml,v 1.25 2001/08/16 03:34:59 dd Exp $
|
||||
-->
|
||||
|
||||
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
|
||||
|
@ -87,6 +87,7 @@
|
|||
</chapter>
|
||||
|
||||
&chap.locking;
|
||||
&chap.kobj;
|
||||
&chap.vm;
|
||||
&chap.dma;
|
||||
&chap.kerneldebug;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
Chapters should be listed in the order in which they are referenced.
|
||||
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/chapters.ent,v 1.9 2001/06/23 04:57:32 murray Exp $
|
||||
$FreeBSD: doc/en_US.ISO8859-1/books/developers-handbook/chapters.ent,v 1.10 2001/07/19 22:06:06 murray Exp $
|
||||
-->
|
||||
|
||||
<!-- Part one -->
|
||||
|
@ -15,6 +15,7 @@
|
|||
<!ENTITY chap.secure SYSTEM "secure/chapter.sgml">
|
||||
|
||||
<!-- Part two -->
|
||||
<!ENTITY chap.kobj SYSTEM "kobj/chapter.sgml">
|
||||
<!ENTITY chap.locking SYSTEM "locking/chapter.sgml">
|
||||
|
||||
<!-- Part three -->
|
||||
|
|
298
en_US.ISO8859-1/books/developers-handbook/kobj/chapter.sgml
Normal file
298
en_US.ISO8859-1/books/developers-handbook/kobj/chapter.sgml
Normal file
|
@ -0,0 +1,298 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
<chapter id="kernel-objects">
|
||||
<title>Kernel Objects</title>
|
||||
|
||||
<para>Kernel Objects, or <firstterm>Kobj</firstterm> provides an
|
||||
object-oriented C programming system for the kernel. As such the
|
||||
data being operated on carries the description of how to operate
|
||||
on it. This allows operations to be added and removed from an
|
||||
interface at run time and without breaking binary
|
||||
compatibility.</para>
|
||||
|
||||
<sect1>
|
||||
<title>Terminology</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Object</term>
|
||||
<listitem><para>A set of data - data structure - data
|
||||
allocation.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Method</term>
|
||||
<listitem>
|
||||
<para>An operation - function.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Class</term>
|
||||
<listitem>
|
||||
<para>One or more methods.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Interface</term>
|
||||
<listitem>
|
||||
<para>A standard set of one or more methods.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Kobj Operation</title>
|
||||
|
||||
<para>Kobj works by generating descriptions of methods. Each
|
||||
description holds a unique id as well as a default function. The
|
||||
description's address is used to uniquely identify the method
|
||||
within a class' method table.</para>
|
||||
|
||||
<para>A class is built by creating a method table associating one
|
||||
or more functions with method descriptions. Before use the class
|
||||
is compiled. The compilation allocates a cache and associates it
|
||||
with the class. A unique id is assigned to each method
|
||||
description within the method table of the class if not already
|
||||
done so by another referencing class compilation. For every
|
||||
method to be used a function is generated by script to qualify
|
||||
arguments and automatically reference the method description for
|
||||
a lookup. The generated function looks up the method by using
|
||||
the unique id associated with the method description as a hash
|
||||
into the cache associated with the object's class. If the method
|
||||
is not cached the generated function proceeds to use the class'
|
||||
table to find the method. If the method is found then the
|
||||
associated function within the class is used; otherwise, the
|
||||
default function associated with the method description is
|
||||
used.</para>
|
||||
|
||||
<para>These indirections can be visualized as the
|
||||
following:</para>
|
||||
|
||||
<programlisting>object->cache<->class</programlisting>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Using Kobj</title>
|
||||
|
||||
<sect2>
|
||||
<title>Structures</title>
|
||||
|
||||
<programlisting>struct kobj_method</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Functions</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>Macros</title>
|
||||
|
||||
<programlisting>KOBJ_CLASS_FIELDS
|
||||
KOBJ_FIELDS
|
||||
DEFINE_CLASS(name, methods, size)
|
||||
KOBJMETHOD(NAME, FUNC)</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Headers</title>
|
||||
|
||||
<programlisting><sys/param.h>
|
||||
<sys/kobj.h></programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Creating an interface template</title>
|
||||
|
||||
<para>The first step in using Kobj is to create an
|
||||
Interface. Creating the interface involves creating a template
|
||||
that the script
|
||||
<filename>src/sys/kern/makeobjops.pl</filename> can use to
|
||||
generate the header and code for the method declarations and
|
||||
method lookup functions.</para>
|
||||
|
||||
<para>Within this template the following keywords are used:
|
||||
<literal>#include</literal>, <literal>INTERFACE</literal>,
|
||||
<literal>CODE</literal>, <literal>METHOD</literal>,
|
||||
<literal>STATICMETHOD</literal>, and
|
||||
<literal>DEFAULT</literal>.</para>
|
||||
|
||||
<para>The <literal>#include</literal> statement and what follows
|
||||
it is copied verbatim to the head of the generated code
|
||||
file.</para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>#include <sys/foo.h></programlisting>
|
||||
|
||||
<para>The <literal>INTERFACE</literal> keyword is used to define
|
||||
the interface name. This name is concatenated with each method
|
||||
name as [interface name]_[method name]. It's syntax is
|
||||
INTERFACE [interface name];.</para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>INTERFACE foo;</programlisting>
|
||||
|
||||
<para>The <literal>CODE</literal> keyword copies its arguments
|
||||
verbatim into the code file. It's syntax is
|
||||
<literal>CODE { [whatever] };</literal></para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>CODE {
|
||||
struct foo * foo_alloc_null(struct bar *)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
};</programlisting>
|
||||
|
||||
<para>The <literal>METHOD</literal> keyword describes a method. It's syntax is
|
||||
<literal>METHOD [return type] [method name] { [object [,
|
||||
arguments]] };</literal></para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>METHOD int bar {
|
||||
struct object *;
|
||||
struct foo *;
|
||||
struct bar;
|
||||
};</programlisting>
|
||||
|
||||
<para>The <literal>DEFAULT</literal> keyword may follow the
|
||||
<literal>METHOD</literal> keyword. It extends the
|
||||
<literal>METHOD</literal> key word to include the default
|
||||
function for method. The extended syntax is
|
||||
<literal>METHOD [return type] [method name] {
|
||||
[object; [other arguments]] }DEFAULT [default
|
||||
function];</literal></para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<programlisting>METHOD int bar {
|
||||
struct object *;
|
||||
struct foo *;
|
||||
int bar;
|
||||
} DEFAULT foo_hack;</programlisting>
|
||||
|
||||
<para>The <literal>STATICMETHOD</literal> keyword is used like
|
||||
the <literal>METHOD</literal> keyword except the kobj data isn't
|
||||
at the head of the object structure so casting to kobj_t would
|
||||
be incorrect. Instead <literal>STATICMETHOD</literal> relies on the Kobj data being
|
||||
referenced as 'ops'. This is also useful for calling
|
||||
methods directly out of a class's method table.</para>
|
||||
|
||||
<para>Other complete examples:</para>
|
||||
|
||||
<programlisting>src/sys/kern/bus_if.m
|
||||
src/sys/kern/device_if.m</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Creating a Class</title>
|
||||
|
||||
<para>The second step in using Kobj is to create a class. A
|
||||
class consists of a name, a table of methods, and the size of
|
||||
objects if Kobj's object handling facilities are used. To
|
||||
create the class use the macro
|
||||
<function>DEFINE_CLASS()</function>. To create the method
|
||||
table create an array of kobj_method_t terminated by a NULL
|
||||
entry. Each non-NULL entry may be created using the macro
|
||||
<function>KOBJMETHOD()</function>.</para>
|
||||
|
||||
<para>For example:</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>The class must be <quote>compiled</quote>. Depending on
|
||||
the state of the system at the time that the class is to be
|
||||
initialized a statically allocated cache, <quote>ops
|
||||
table</quote> have to be used. This can be accomplished by
|
||||
declaring a <structname>struct kobj_ops</structname> and using
|
||||
<function>kobj_class_compile_static();</function> otherwise,
|
||||
<function>kobj_class_compile()</function> should be used.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Creating an Object</title>
|
||||
|
||||
<para>The third step in using Kobj involves how to define the
|
||||
object. Kobj object creation routines assume that Kobj data is
|
||||
at the head of an object. If this in not appropriate you will
|
||||
have to allocate the object yourself and then use
|
||||
<function>kobj_init()</function> on the Kobj portion of it;
|
||||
otherwise, you may use <function>kobj_create()</function> to
|
||||
allocate and initialize the Kobj portion of the object
|
||||
automatically. <function>kobj_init()</function> may also be
|
||||
used to change the class that an object uses.</para>
|
||||
|
||||
<para>To integrate Kobj into the object you should use the macro
|
||||
KOBJ_FIELDS.</para>
|
||||
|
||||
<para>For example</para>
|
||||
|
||||
<programlisting>struct foo_data {
|
||||
KOBJ_FIELDS;
|
||||
foo_foo;
|
||||
foo_bar;
|
||||
};</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Calling Methods</title>
|
||||
|
||||
<para>The last step in using Kobj is to simply use the generated
|
||||
functions to use the desired method within the object's
|
||||
class. This is as simple as using the interface name and the
|
||||
method name with a few modifications. The interface name
|
||||
should be concatenated with the method name using a '_'
|
||||
between them, all in upper case.</para>
|
||||
|
||||
<para>For example, if the interface name was foo and the method
|
||||
was bar then the call would be:</para>
|
||||
|
||||
<programlisting>[return value = ] FOO_BAR(object [, other parameters]);</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Cleaning Up</title>
|
||||
|
||||
<para>When an object allocated through
|
||||
<function>kobj_create()</function> is no longer needed
|
||||
<function>kobj_delete()</function> may be called on it, and
|
||||
when a class is no longer being used
|
||||
<function>kobj_class_free()</function> may be called on it.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-declaration: "../chapter.decl"
|
||||
sgml-indent-data: t
|
||||
sgml-omittag: nil
|
||||
sgml-always-quote-attributes: t
|
||||
sgml-parent-document: ("../book.sgml" "part" "chapter")
|
||||
End:
|
||||
-->
|
Loading…
Reference in a new issue