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> <sys/kobj.h>
Первый шаг при использовании Kobj заключается в создании интерфейса. Создание интерфейса включает создание шаблона, который может использоваться скриптом src/sys/kern/makeobjops.pl для генерации файла объявлений и кода для объявлений метода и функций поиска методов.
Внутри этого шаблона используются следующие ключевые слова: #include, INTERFACE, CODE, METHOD, STATICMETHOD и DEFAULT.
Директива #include и то, что следует далее, без изменений копируется в начало файла генерируемого кода.
Например:
#include <sys/foo.h>
Ключевое слово INTERFACE используется для определения имени интерфейса. Это имя объединяется с именем каждого метода в виде [имя интерфейса]_[имя метода]. Он имеет синтаксис INTERFACE [имя интерфейса];.
Например:
INTERFACE foo;
Ключевое слово CODE копирует свои аргументы без изменений в файл кода. Он имеет синтаксис CODE { [нечто] };
Например:
CODE { struct foo * foo_alloc_null(struct bar *) { return NULL; } };
Ключевое слово METHOD описывает метод. Его синтаксис METHOD [возвращаемый тип] [имя метода] { [объект [, аргументы]] };
For example:
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_t будет некорректным. Вместо этого STATICMETHOD опирается на данные Kobj, на которые ссылаются как 'ops'. Это также полезно для непосредственного вызова методов из таблицы методов класса.
Другие законченные примеры:
src/sys/kern/bus_if.m src/sys/kern/device_if.m
Второй шаг при использовании Kobj заключается в создании класса. Класс состоит из имени, таблицы методов и размера объектов, если использовались механизмы обработки объекта Kobj. Для создания класса воспользуйтесь макросом 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". Это может быть достигнуто объявлением struct kobj_ops и использованием kobj_class_compile_static();, в противном случае должна быть использована функция kobj_class_compile().
Третий шаг в использовании Kobj включает и то, как определить объект. Процедуры создания объекта Kobj предполагают, что данные Kobj располагаются в начале объекта. Если это не подходит, то вам нужно распределить оюхект самостоятельно и затем воспользоваться функцией kobj_init() над его частью, относящейся к Kobj; в противном случае вы можете использовать функцию kobj_create() для выделения и инициализации части Kobk объекта автоматически. kobj_init() можно также использовать для изменения класса, который использует объект.
Для интеграции Kobj в объект, вы должны использовать макрос KOBJ_FIELDS.
Например
struct foo_data { KOBJ_FIELDS; foo_foo; foo_bar; };
Последний шаг в использовании Kobj сводится просто к использованию сгенерированных функция для вызова требуемого метода из класса объекта. Это также просто, как использование имени интерфейса и имени метода с некоторыми модификациями. Имя интерфейса должно быть объединено с именем метода через символ '_' между ними, все в верхнем регистре.
К примеру, если имя интерфейса было foo, а метод назывался bar, то вызов будет таким:
[return value = ] FOO_BAR(object [, other parameters]);
Когда объект, распределенный через kobj_create(), больше не нужен, то над ним может быть выполнена функция kobj_delete(), а когда класс больше не используется, то над ним может быть выполнен вызов kobj_class_free().