Справочное описание GObject |
---|
Как только интерфейс определён, его реализация довольно тривиальна. Исходный код, показывающий как это делается для
определённого интерфейса IBaz в предыдущем разделе, расположен в
sample/interface/maman-baz.{h|c}
.
Первый шаг - определяем обычную GType. Здесь мы решили использовать GType которая наследует GObject. Её имя MamanBaz:
#ifndef MAMAN_BAZ_H
#define MAMAN_BAZ_H
#include <glib-object.h>
#define MAMAN_TYPE_BAZ (maman_baz_get_type ())
#define MAMAN_BAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAZ, Mamanbaz))
#define MAMAN_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MAMAN_TYPE_BAZ, MamanbazClass))
#define MAMAN_IS_BAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAZ))
#define MAMAN_IS_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MAMAN_TYPE_BAZ))
#define MAMAN_BAZ_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MAMAN_TYPE_BAZ, MamanbazClass))
typedef struct _MamanBaz MamanBaz;
typedef struct _MamanBazClass MamanBazClass;
struct _MamanBaz {
GObject parent;
int instance_member;
};
struct _MamanBazClass {
GObjectClass parent;
};
GType maman_baz_get_type (void);
#endif //MAMAN_BAZ_H
В этом заголовке нет ничего сверхъестественного или страшного: он не определяет никакого особенного API и не наследует особенный тип.
Второй шаг - реализация maman_baz_get_type
:
GType
maman_baz_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GTypeInfo info = {
sizeof (MamanBazClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (MamanBaz),
0, /* n_preallocs */
baz_instance_init /* instance_init */
};
static const GInterfaceInfo ibaz_info = {
(GInterfaceInitFunc) baz_interface_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
type = g_type_register_static (G_TYPE_OBJECT,
"MamanBazType",
&info, 0);
g_type_add_interface_static (type,
MAMAN_TYPE_IBAZ,
&ibaz_info);
}
return type;
}
Эта функция очень похожа на подобные функции рассматриваемые нами ранее. Единственный интерфейсно-специфичный код представленный здесь
это вызов g_type_add_interface_static
который используется для информирования системы типов что зарегистрированный тип
GType также реализует интерфейс
MAMAN_TYPE_IBAZ
.
baz_interface_init
, функция инициализации интерфейса, она тоже очень проста:
static void baz_do_action (MamanBaz *self)
{
g_print ("Baz implementation of IBaz interface Action: 0x%x.\n", self->instance_member);
}
static void
baz_interface_init (gpointer g_iface,
gpointer iface_data)
{
MamanIbazInteface *iface = (MamanIbazInteface *)g_iface;
iface->do_action = (void (*) (MamanIbaz *self))baz_do_action;
}
static void
baz_instance_init (GTypeInstance *instance,
gpointer g_class)
{
MamanBaz *self = MAMAN_BAZ(instance);
self->instance_member = 0xdeadbeaf;
}
baz_interface_init
просто инициализирует интерфейсные методы для реализации определённого
MamanBaz: maman_baz_do_action
не делает ничего полезного но могла бы :)