Справочное описание GObject |
---|
Большая часть определения интерфейса уже показана “Non-instantiable classed types: Interfaces.”
но я чувствую что нужно показать как конкретно создаётся интерфейс. Исходные коды примеров связанных с этим разделом можно найти
в исходном пакете документации, в файле sample/interface/maman-ibaz.{h|c}
.
Как и раньше, сначала получаем правильный заголовок:
#ifndef MAMAN_IBAZ_H
#define MAMAN_IBAZ_H
#include <glib-object.h>
#define MAMAN_TYPE_IBAZ (maman_ibaz_get_type ())
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
#define MAMAN_IS_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
#define MAMAN_IBAZ_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_TYPE_IBAZ, MamanIbazInterface))
typedef struct _MamanIbaz MamanIbaz; /* макет объекта */
typedef struct _MamanIbazInterface MamanIbazInterface;
struct _MamanIbazInterface {
GTypeInterface parent;
void (*do_action) (MamanIbaz *self);
};
GType maman_ibaz_get_type (void);
void maman_ibaz_do_action (MamanIbaz *self);
#endif /*MAMAN_IBAZ_H*/
Этот код похож на обычную GType которая наследует GObject за исключением некоторых деталей:
_GET_CLASS
макрос называется _GET_INTERFACE
и реализуется не с помощью G_TYPE_INSTANCE_GET_CLASS
, а с помощью
G_TYPE_INSTANCE_GET_INTERFACE
.
Тип экземпляра MamanIbaz определён не полностью: он используется просто как абстрактный тип который представляет экземпляр любого объекта реализующего интерфейс.
Реализация самого типа MamanIbaz тривиальна:
maman_ibaz_get_type
регистрирует тип в системе типов.
maman_ibaz_base_init
как ожидается регистрирует интерфейсные сигналы если они есть
(позже мы рассмотрим как их использовать). Убедитесь что используете статичную локальную логическую переменную
чтобы не выполнять код инициализации дважды (как описано в
“Interface Initialization”,
base_init
выполняется один раз для каждой реализованной инстанциации интерфейса)
maman_ibaz_do_action
разыменовывает структуру класса
для доступа к связанным с ней функциям класса и их вызова.
static void
maman_ibaz_base_init (gpointer g_class)
{
static gboolean initialized = FALSE;
if (!initialized) {
/* здесь создаём сигналы интерфейса. */
initialized = TRUE;
}
}
GType
maman_ibaz_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GTypeInfo info = {
sizeof (MamanIbazInterface),
maman_ibaz_base_init, /* base_init */
NULL, /* base_finalize */
NULL, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL /* instance_init */
};
type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbaz", &info, 0);
}
return type;
}
void maman_ibaz_do_action (MamanIbaz *self)
{
MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
}