Как определить реализацию Интерфейса?

Как только интерфейс определён, его реализация довольно тривиальна. Исходный код, показывающий как это делается для определённого интерфейса 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 не делает ничего полезного но могла бы :)