• 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
     */
    
  • 相关阅读:
    python函数应用
    python文件操作
    设计模式大杂烩(24种设计模式的总结以及学习设计模式的几点建议)
    (二十四)解释器模式详解
    (二十三)原型模式详解(clone方法源码的简单剖析)
    (二十二)访问者模式详解(伪动态双分派)
    (二十一)状态模式详解(DOTA版)
    (二十)职责链模式详解(都市异能版)
    (十九)组合模式详解
    (十八)享元模式详解(都市异能版)
  • 原文地址:https://www.cnblogs.com/silvermagic/p/9087893.html
Copyright © 2020-2023  润新知