The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

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

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




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру