2
16
2011
0

GObject简单示例

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!

Category: 编程 | Tags: | Read Count: 2838

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Powered by Chito | Hosted at is-Programmer | Theme: Aeros 2.0 by TheBuckmaker.com