gobject 中 g_object_new 流程简介

来源:互联网 发布:js如何定义变量 编辑:程序博客网 时间:2024/06/07 22:27

http://blog.csdn.net/giesus/article/details/5891773
g_object_new的函数签名是这样的:

gpointerg_object_new (GType      object_type,            const gchar *first_property_name,            ...)

这个函数是个可变参数的函数, 第一个参数是需要创建的对象的类型, 当使用 g_object_new 来创建对象的时候, 这个参数是必须的, 同时它还要求这个函数所创建 的对象必须是GObject的子对象. 在我们定义自己的对象时, 必须要在系统中注册自己的 类型, 这里的系统指的是 glib 的系统, 即 glib 自己维护的一套数据结构. 一般可以用 如下方式进行:

/* 这里使用gtk_gadget作为例子,  * 一般来说 gtk_ 表示命名空间,  * gadget_表示对象名字. *//******** .h ***********/GType gtk_gadget_get_type(void);/******** .c ***********/G_DEFINE_TYPE(GtkGadget, gtk_gadget, G_TYPE_OBJECT)

G_DEFINE_TYPE 宏会声明一些函数, 并且实现了 gtk_gadget_get_type(void), G_DEFINE_TYPE 是在 gtype.h 中定义的下面是个例子, 这个例子来自于 gobject 的参考 手册:

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);}GTypegtk_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,                                       (GTypeFlags) flags);      {       /* 这是接口部分, 这里不涉及.         static 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;}

代码中, 最关键的部分是:

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,                              (GTypeFlags) flags);

g_type_register_static_simple 这个函数的作用, 就是将用户自己定义的类型注册到系 统中, 从上面的代码我们还可以看出, G_DEFINE_TYPE 声明了两个函数, 但是并没有实现, 需要定义对象的用户自己去实现, 这两个函数是:

static void     gtk_gadget_init       (GtkGadget      *self);static void     gtk_gadget_class_init (GtkGadgetClass *klass);

这两个函数是对象的初始化函数, 相当于C++中的构造函数, 第一个函数在每个对象创建的 时候都会被调用, 第二个函数只有在第一次创建对象的时候才会被调用. 确切的说, 是调 用 g_type_class_ref 时, 如果 class 没有初始化, 就会调用 gtk_gadget_class_init. 具体的调用点见后面. 先说一下第二个参数, 从第二个参数开始, 表示的是 object 的属性, 它们都是成对出现的, 如果没有属性需要在创建对象的时候设 置, 则第二个参数设置成 NULL. 如果有属性要设置, 那么最后一个参数也要设置成 NULL. 一个来自于 gtk 的例子(gtk 中的对象, 都是继承自gobject):

/* 没有属性 */g_object_new (GTK_TYPE_TOOL_ITEM, NULL);/* 有一个属性 */g_object_new (GTK_TYPE_TOOL_ITEM_GROUP, "label", label, NULL);

下面来看整个的调用过程, 一般调用的方式为:

g_object_new(gtk_gadget_get_type(), NULL);

这里我们假设没有属性需要设置. 在真实的代码中, 我们一般会定义一个宏来使用 gtk_gadget_get_type():

GTK_TYPE_GADGET (gtk_gadget_get_type())

所以一般的我们会写成:

g_object_new (GTK_TYPE_GADGET, NULL);

这样看上去更加的清晰.

GTK_TYPE_GADGET 会取得这个对象的类型, 在 glib 中, 这个类型是一个唯一标示符. g_object_new 首先会确认 object_type (g_object_new 的第一个参数)是否是一个 gobject 对象. 然后检查是否有属性值需要设置, 如果属性值为 NULL, 那么直接调用 g_object_newv. 如果需要设置属性值, 则调用 g_object_new_valist.

g_object_newv 的原型是:

gpointerg_object_newv (GType       object_type,               guint       n_parameters,               GParameter *parameters)

这个函数的具体功能可以参考手册, g_object_new 是这样调用这个函数的:

g_object_newv(object_type, 0, NULL);

g_object_newv 会调用 g_type_class_peek_static(object_type) 来取得 object_type的 class, 如果取回来的 class 为空, 那么就会调用 g_type_class_ref(object_type), g_type_class_ref 会查找 node, node 中会记录 class 相关信息, 如果 class 没有初始 化, 那么会调用 type_class_init_Wm. type_class_init_Wm 会初始化 class, 如果在注 册类型的时候指定了 class_init, 那么会调用 class_init. 接下来, 由于传递给 g_object_newv 的 n_parameters 和 parameters 都为空, 所以会直接调用 gobject class 的constructor 来构造对象. constructor 是 gobject class 的一个函数. 一般是 g_object_constructor, 用户可以创建自己的 constructor 函数, 在自定义对象的 class_init 中将 GObject 中的 constructor, 改成自己需要的 constructor. 这样的行 为类似于 C++ 中的需函数. g_object_constructor 会调用 g_type_create_instance 来 创建对象实例(分配内存), g_type_create_instance 会调依次调用祖先对象的初始化函 数,调用完成后再调用自己对象的初始化函数, 在这里就是 gtk_gadget_init. 调用关系 如下:

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1566) | 评论(0) | 转发(0) |
0

上一篇:Spice 分析(1) – 构建 Spice 开发环境

下一篇:SPICE之spicy主函数源码分析

相关热门文章
  • linux 常见服务端口
  • xmanager 2.0 for linux配置
  • 【ROOTFS搭建】busybox的httpd...
  • openwrt中luci学习笔记
  • 什么是shell
  • linux dhcp peizhi roc
  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新...
  • sed -e "/grep/d" 是什么意思...
  • 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
原创粉丝点击