Glib之GObject宏介绍

G_DEFINE_TYPE定义一个静态类型

/**
 * G_DEFINE_TYPE(`G_DEFINE_TYPE_WITH_CODE`比`G_DEFINE_TYPE`就是多了一个自定义代码参数_C_):
 * @TN: 新类型的名字,单词首字母大写,例如:GtkGadget。
 * @t_n: 新类型的名字,单词全部小写并且用'_'符号分隔,例如gtk_gadget:
 *  separated by '_'.
 * @T_P: 父类型的#GType,例如:GTK_TYPE_WIDGET
 */
#define G_DEFINE_TYPE(TN, t_n, T_P)        G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {})

/**
 * @TN: 新类型的名字,单词首字母大写,例如:GtkGadget。
 * @t_n: 新类型的名字,单词全部小写并且用'_'符号分隔,例如gtk_gadget:
 *  separated by '_'.
 * @T_P: 父类型的#GType,例如:GTK_TYPE_WIDGET
 * @_f_: 传递给g_type_register_static()函数的参数#GTypeFlags
 * @_C_: 插入*_get_type()函数的自定义代码
 *
 */
#define G_DEFINE_TYPE_EXTENDED(TN, t_n, T_P, _f_, _C_)        _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, _f_) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()

接下来我们来看下G_DEFINE_TYPE_EXTENDED展开后的代码

  • _G_DEFINE_TYPE_EXTENDED_BEGIN

实现type_name##_get_type函数的前半部

#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
\
static void     type_name##_init              (TypeName        *self); \
static void     type_name##_class_init        (TypeName##Class *klass); \
static gpointer type_name##_parent_class = NULL; \
static gint     TypeName##_private_offset; \
\
_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
\
G_GNUC_UNUSED \
static inline gpointer \
type_name##_get_instance_private (TypeName *self) \
{ \
  return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \
} \
\
GType \
type_name##_get_type (void) \
{ \
  static volatile gsize g_define_type_id__volatile = 0; \
  if (g_once_init_enter (&g_define_type_id__volatile))  \
    { \
      GType g_define_type_id = \
        g_type_register_static_simple (TYPE_PARENT, \
                                       g_intern_static_string (#TypeName), \
                                       sizeof (TypeName##Class), \
                                       (GClassInitFunc) type_name##_class_intern_init, \
                                       sizeof (TypeName), \
                                       (GInstanceInitFunc) type_name##_init, \
                                       (GTypeFlags) flags); \
      { /* custom code follows */
  • _C_

将自定义代码插入type_name##_get_type函数的中部,自定义代码将被/* custom code follows *//* following custom code */ 处的{}所包裹

  • _G_DEFINE_TYPE_EXTENDED_END

实现type_name##_get_type函数的后半部

#define _G_DEFINE_TYPE_EXTENDED_END()    \
        /* following custom code */    \
      }                    \
      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
    }                    \
  return g_define_type_id__volatile;    \
} /* closes type_name##_get_type() */

样例

* |[<!-- language="C" -->
 * G_DEFINE_TYPE_EXTENDED (GtkGadget,
 *                         gtk_gadget,
 *                         GTK_TYPE_WIDGET,
 *                         0,
 *                         G_IMPLEMENT_INTERFACE (TYPE_GIZMO,
 *                                                gtk_gadget_gizmo_init));
 * ]|
 * expands to
 * |[<!-- language="C" -->
 * static void     gtk_gadget_init       (GtkGadget      *self);
 * static void     gtk_gadget_class_init (GtkGadgetClass *klass);
 * static gpointer gtk_gadget_parent_class = NULL;
 * static void     gtk_gadget_class_intern_init (gpointer klass)
 * {
 *   gtk_gadget_parent_class = g_type_class_peek_parent (klass);
 *   gtk_gadget_class_init ((GtkGadgetClass*) klass);
 * }
 *
 * GType
 * gtk_gadget_get_type (void)
 * {
 *   static volatile gsize g_define_type_id__volatile = 0;
 *   if (g_once_init_enter (&g_define_type_id__volatile))
 *     {
 *       GType g_define_type_id =
 *         g_type_register_static_simple (GTK_TYPE_WIDGET,
 *                                        g_intern_static_string ("GtkGadget"),
 *                                        sizeof (GtkGadgetClass),
 *                                        (GClassInitFunc) gtk_gadget_class_intern_init,
 *                                        sizeof (GtkGadget),
 *                                        (GInstanceInitFunc) gtk_gadget_init,
 *                                        0);
 *       {
 *         const GInterfaceInfo g_implement_interface_info = {
 *           (GInterfaceInitFunc) gtk_gadget_gizmo_init
 *         };
 *         g_type_add_interface_static (g_define_type_id, TYPE_GIZMO, &g_implement_interface_info);
 *       }
 *       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
 *     }
 *   return g_define_type_id__volatile;
 * }
 * ]|
 * 必须要手动实现的就是实例和类结构的定义,以及实例和类初始化函数的定义
 *
 * Since: 2.4
 */
posted @ 2018-05-25 12:13  银魔术师  阅读(2187)  评论(0编辑  收藏  举报