引子——
这几天研究GObject系统,网上找了很多资料,但都让我觉得很头疼。
首先资料有官方的手册,在gtk.org上;
然后可以google到有人翻译的中文版,不过挺长的,看起来晕晕的;
还能找到另外的一个Gobject Tutorial:http://www.zooyoo.org/gobject-tutorial.html
这第三个最容易看了,不过上面给出了两个程序,这第一个嘛,我拷下来运行是可以的。而这第二个么,不全啊~~,弄了好久也不能正常运行。
后来在cnblog上找到了一个人写的事例程序,很抱歉我忘记了URL了,知道的告诉我加上哈~,在这里谢谢作者了。
程序包叫gobject_test,里面用到了比较复杂的程序,信号都上去了,我目前还不打算搞那么复杂。
于是结合这个事例代码,以及zooyoo上的someobject程序,弄了一上午,终于弄出一个可以运行的最小的GObject程序出来。
其功能是:新建一个自己的对象,也就是一个object,然后经过一系列的操作,可以使用g_object_new来在main函数中生成一个对象。
当然,复杂的程序还可以用到它的方法,访问私有数据,设置回调函数等等。不过我们这是简单的事例,因此只用到了最简单的。
代码总共60几行,就比较容易入门啦。
下面直接上代码:
#include<glib-object.h>
#define SOME_OBJECT_TYPE (some_object_get_type())
#define SOME_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SOME_OBJECT_TYPE, SomeObject))
#define SOME_IS_OBJECT(obj) (GTYPE_CHECK_TYPE((obj), SOME_OBJECT_TYPE))
#define SOME_OBJECT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), SOME_OBJECT_TYPE,SomeObjectClass))
#define SOME_IS_OBJECT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), SOME_OBJECT_TYPE))
#define SOME_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SOME_OBJECT_TYPE, SomeObjectClass))
typedef struct _SomeObject SomeObject;
struct _SomeObject {
GObject parent_obj;
};
typedef struct _SomeObjectClass SomeObjectClass;
struct _SomeObjectClass {
GObjectClass parent_class;
};
G_DEFINE_TYPE (SomeObject, some_object, G_TYPE_OBJECT)
void some_object_dispose(GObject *gobject)
{
SomeObject *slef = SOME_OBJECT(gobject);
g_print("-- %s # %i\n",__func__, __LINE__);
G_OBJECT_CLASS(some_object_parent_class)->dispose(gobject);
}
void some_object_finalize(GObject *gobject)
{
SomeObject *self = SOME_OBJECT(gobject);
g_print("-- %s # %i\n",__func__, __LINE__);
G_OBJECT_CLASS(some_object_parent_class)->finalize(gobject);
}
static void some_object_class_init(SomeObjectClass* g_class)
{
GObjectClass *this_class = G_OBJECT_CLASS(g_class);
GParamSpec *spec;
g_print("-- %s # %i\n",__func__, __LINE__);
this_class->dispose = &some_object_dispose;
this_class->finalize = &some_object_finalize;
}
void some_object_init(SomeObject *self)
{
g_print("-- %s # %i\n",__func__, __LINE__);
g_object_set(G_OBJECT(self),NULL,0,NULL,NULL,NULL);
}
int main()
{
g_print("****init the type system****\n");
g_type_init();
g_print("****init type system OK ****\n");
SomeObject *testobj = g_object_new(SOME_OBJECT_TYPE, NULL);;
g_object_unref(testobj);
g_print("****finish GObject Demo ****\n");
return 0;
}
上面是someobject.smallest.c文件,下面给出MAKEFILE文件:
CC = gcc
PROG_NAME = gobject_test
SRCS = someobject.smallest.c
OBJS = someobject.smallest.o
LIBS = glib-2.0
CFLAGS += -I/usr/include/glib-2.0
CFLAGS += -I/usr/lib/glib-2.0/include
LDFLAGS += -lglib-2.0
LDFLAGS += -lgobject-2.0
all: ${PROG_NAME}
${PROG_NAME}:${OBJS}
${CC} -o ${PROG_NAME} ${OBJS} ${LDFLAGS} ${CFLAGS}
.c.o:
${CC} -c {1}lt; ${CFLAGS}
clean:
rm -f *.o ${PROG_NAME}
rebuild: clean all
这里面要注意的是,除了要-lglib之外还要-lgobject。其路径都可以用`pkg-config --cflags --libs glib-2.0/gobject-2.0`来获取。
另外提到一点注意地方是:
声明对象的结构体和类结构体的时候,错误的类型会导致:specified calss size for type `xxx` is smaller than the parent type's `GObject` class size。这是因为定义的class中类型不对,要用GObjectClass
最后,这个程序调通了,我还是很高兴的,万里长征第一步终于迈开了,以后应该就可以慢慢分析学习了。