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
函數的前半部code
#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 */
處的{}
所包裹get
_G_DEFINE_TYPE_EXTENDED_END
宏實現type_name##_get_type
函數的後半部string
#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 */