Gobject终于研究出来了(这个示例还没涉及到另外两个重要概念——信号/Signals,属性/Properties)。。。
声明:本代码直接参考GTK+代码实现,严格按照(最差也就是接近)GNOME标准书写。
演示了简单的继承功能(gobj规定所有类均直接或间接地基于GObject类)、私有成员、公有成员、构造函数和析构函数,而且也不是很难,很容易看懂。
直接在终端执行以下代码(发现直接复制粘贴容易出错,所以大家最好先存为一个.sh文件,然后允许它即可)
## begin funperson.h ## cat >> funperson.h << EOF #ifndef __FUN_PERSON_H__ #define __FUN_PERSON_H__ #include <glib-object.h> G_BEGIN_DECLS #define FUN_PERSON_TYPE (fun_person_get_type ()) #define FUN_PERSON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FUN_PERSON_TYPE, FunPerson)) #define FUN_PERSON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FUN_PERSON_TYPE, FunPersonClass)) #define FUN_IS_PERSON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FUN_PERSON_TYPE)) #define FUN_IS_PERSON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FUN_PERSON_TYPE)) #define FUN_GET_PERSON_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FUN_PERSON_TYPE, FunPersonClass)) typedef struct _FunPerson FunPerson; typedef struct _FunPersonPrivate FunPersonPrivate; typedef struct _FunPersonClass FunPersonClass; struct _FunPerson { GObject parent; /*< private >*/ //这儿很有意思,emacs会加亮private和public FunPersonPrivate *priv; /*< public >*/ GString *name; }; struct _FunPersonClass { GObjectClass parent_class; }; GType fun_person_get_type (void); FunPerson *fun_person_new (void); FunPerson *fun_person_new_with_name (gchararray bloodtype); void fun_person_set_blood_type (FunPerson *obj, gchararray bloodtype); gchararray fun_person_get_blood_type (FunPerson *obj); void fun_person_set_name (FunPerson *obj, gchararray name); gchararray fun_person_get_name (FunPerson *obj); G_END_DECLS #endif /* __FUN_PERSON_H__ */ EOF ## End Of funperson.h ## ## Begin funperson.c ## cat >> funperson.c << EOF #include <glib.h> #include "funperson.h" struct _FunPersonPrivate { gchararray bloodtype; }; G_DEFINE_TYPE (FunPerson, fun_person, G_TYPE_OBJECT) enum { PROP_0 /* 没有属性和信号 */ }; static void fun_person_dispose (GObject *gobject) { /* TODO: 添加需要解除引用的对象 */ /* TIP: dispose可能会被调用多次,所以必须使用g_object_undef解除引用 */ G_OBJECT_CLASS (fun_person_parent_class)->dispose (gobject); } static void fun_person_finalize (GObject *gobject) { /* TODO: 添加析构代码到这里 */ FunPerson *self = FUN_PERSON (gobject); if (self->priv->bloodtype) { g_free (self->priv->bloodtype); self->priv->bloodtype = NULL; } if (self->name) { g_string_free (self->name, TRUE); self->name = NULL; } g_print ("A person was dead!\n"); G_OBJECT_CLASS (fun_person_parent_class)->finalize (gobject); } FunPerson *fun_person_new () { FunPerson *obj; obj = g_object_new (FUN_PERSON_TYPE, NULL); return obj; } static void fun_person_class_init (FunPersonClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = fun_person_dispose; gobject_class->finalize = fun_person_finalize; g_type_class_add_private (gobject_class, sizeof(FunPersonPrivate)); } static void fun_person_init (FunPerson *obj) { /* TODO: 添加初始化代码到这里 */ obj->priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, FUN_PERSON_TYPE, FunPersonPrivate); g_print ("A person was born!\n"); } FunPerson *fun_person_new_with_name (gchararray name) { FunPerson *obj; FunPersonPrivate *priv; obj = fun_person_new (); g_return_if_fail (obj>0); fun_person_set_name (obj, name); return obj; } void fun_person_set_blood_type (FunPerson *obj, gchararray bloodtype) { FunPersonPrivate *priv; gchararray newstr; g_return_if_fail (FUN_IS_PERSON (obj)); priv = obj->priv; g_return_if_fail (priv != NULL); newstr = g_strdup (bloodtype); g_free (priv->bloodtype); priv->bloodtype = newstr; } gchararray fun_person_get_blood_type (FunPerson *obj) { g_return_if_fail (FUN_IS_PERSON(obj)); return obj->priv->bloodtype; } void fun_person_set_name (FunPerson *self, gchararray name) { GString *gstr; g_return_if_fail ((name != NULL) && (FUN_IS_PERSON (self))); gstr = g_string_new (name); g_return_if_fail (gstr != NULL); if (self->name) g_string_free (self->name, TRUE); self->name = gstr; } gchararray fun_person_get_name (FunPerson *self) { g_return_if_fail (FUN_IS_PERSON (self)); return self->name->str; } EOF ## end of file ## ## begin main.c ## cat >> main.c << EOF #include <glib.h> #include "funperson.h" gint main () { g_type_init (); /* init gtype */ FunPerson *per = fun_person_new_with_name ("Tom"); fun_person_set_blood_type (per, "AB"); g_print ("%s's blood type is %s\n", fun_person_get_name (per),fun_person_get_blood_type (per)); g_object_unref (per); /* free the object */ per = fun_person_new (); fun_person_set_name (per, "Mike"); fun_person_set_blood_type (per, "B"); g_print ("Hi, all.\n%s makes this app. %s's blood type is %s\n", fun_person_get_name (per), fun_person_get_name (per), fun_person_get_blood_type (per)); g_object_unref (per); return 0; } EOF ## end of main.c ##
然后就可以在这个目录下找到funperson.[ch]和main.c了
编译
cc main.c funperson.c $(pkg-config --cflags --libs gobject-2.0 glib-2.0)
运行
./a.out
结果
A person was born!
Tom's blood type is AB
A person was dead!
A person was born!
Hi, all.
Mike makes this app. Mike's blood type is B
A person was dead!