Gobject tutorial 五

参考:GObject – 2.0: Type System Concepts

Type System Concepts

The GLib Dynamic Type System

在GLib中,类型的概念比通常所理解的Ojbect type更宽泛。我们将对新类型注册到类型系统时使用的函数及数据结构进行了解,来对此进行说明。

typedef struct _GTypeInfo               GTypeInfo;
struct _GTypeInfo
{/* interface types, classed types, instantiated types */guint16                class_size;GBaseInitFunc          base_init;GBaseFinalizeFunc      base_finalize;/* classed types, instantiated types */GClassInitFunc         class_init;GClassFinalizeFunc     class_finalize;gconstpointer          class_data;/* instantiated types */guint16                instance_size;guint16                n_preallocs;GInstanceInitFunc      instance_init;/* value handling */const GTypeValueTable *value_table;
};GType
g_type_register_static (GType            parent_type,const gchar     *type_name,const GTypeInfo *info,GTypeFlags       flags);GType
g_type_register_fundamental (GType                       type_id,const gchar                *type_name,const GTypeInfo            *info,const GTypeFundamentalInfo *finfo,GTypeFlags                  flags);

 上面的函数用于将新的类型(GType)注册到类型系统。通常,我们使用的是g_type_register_static。基础类型属于最顶层的类型,他们不由任何类型衍生而来,这意味着非基础类型都是由其他类型衍生而来。

不管是基础类型还是非基础类型,它们都是由GTypeInfo来定义的。这也说明了类型概念在GLiib中是要比GObject type更宽。

下面将对GTypeInfo的成员进行说明。

  • class_size:类所占空间大小,对于GOjbect来说,此值就是sizeof(GObjectClass)
  • base_init、class_init:类初始化函数,相当于C++中的构造函数。
  • base_finalize、class_finalize:类销毁函数。相当于C++中的析构函数。
  • instance_size:实例所占空间大小,对于GObject来说,此值就是sizeof(GObject).
  • n_preallocs:initialization policy, 相当于C++ type of new opeartor.
  • value_table: 复制函数,相当于C++ copy opeartors.

Copy functions

对于GLib的所有类型来说,它们的主要的共同点是,它们都能通过简单的API来进行复制。

比如说,GValue做为所有类型的一个抽象容器。它的简单函数g_value_cope能够获取到类型的value_table,并进行GVaule到GValue的内容复制。

下面举例说明:

static void test_int (void)
{GValue a_value = G_VALUE_INIT;GValue b_value = G_VALUE_INIT;guint64 a, b;a = 0xdeadbeef;g_value_init (&a_value, G_TYPE_UINT64);g_value_set_uint64 (&a_value, a);g_value_init (&b_value, G_TYPE_UINT64);g_value_copy (&a_value, &b_value);b = g_value_get_uint64 (&b_value);if (a == b) {g_print ("Yay !! 10 lines of code to copy around a uint64.\n");} else {g_print ("Are you sure this is not a Z80 ?\n");}
}static void test_object (void)
{GObject *obj;GValue obj_vala = G_VALUE_INIT;GValue obj_valb = G_VALUE_INIT;obj = g_object_new (VIEWER_TYPE_FILE, NULL);g_value_init (&obj_vala, VIEWER_TYPE_FILE);g_value_set_object (&obj_vala, obj);g_value_init (&obj_valb, G_TYPE_OBJECT);/* g_value_copy's semantics for G_TYPE_OBJECT types is to copy the reference.* This function thus calls g_object_ref.* It is interesting to note that the assignment works here because* VIEWER_TYPE_FILE is a G_TYPE_OBJECT.*/g_value_copy (&obj_vala, &obj_valb);g_object_unref (G_OBJECT (obj));g_object_unref (G_OBJECT (obj));
}

Conventions

下面我们介绍几个常用宏及其作用:

  • PREFIX_TYPE_OBJECT:返回相关对象的GType。例如,GTK_TYPE_WIDGET。
  • PREFIX_OBJECT(obj):将obj转换为PrefixObject.例如,GTK_WIDGET(widget)。
  • PREFIX_OBJECT_CLASS(klass):将klass转换为PrefixObjectClass。例如,GTK_WIDGET_CLASS。
  • PREFIX_IS_OBJECT(obj):判断obj是否为OBJECT类型,并返回一个布尔值。例如,GTK_IS_WIDGE。
  • PREFIX_IS_OBJECT_CLASS(klass):判断klass是否是OBJECT类型的类。并返回一个布尔值。例如,GTK_IS_WIDGE_CLASS。
  • PREFIX_OBJECT_GET_CLASS(obj):返回obj实例所对应 的类指针。

Non-instantiatable non-classed fundamental types

很多类型既不能被类型系统实例化也没有所属的类。它们中大部分都是基础类型,比如说gchar.它们由GLib注册。

那,如果我们要生成一个这样的类型,咋办呢?我们先来看看glib中gchar是怎么注册的。

/* --- type initialization --- */
void
_g_value_types_init (void)
{GTypeInfo info = {0,				/* class_size */NULL,			/* base_init */NULL,			/* base_destroy */NULL,			/* class_init */NULL,			/* class_destroy */NULL,			/* class_data */0,				/* instance_size */0,				/* n_preallocs */NULL,			/* instance_init */NULL,			/* value_table */};const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };GType type G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;/* G_TYPE_CHAR / G_TYPE_UCHAR*/{static const GTypeValueTable value_table = {value_init_long0,		/* value_init */NULL,			/* value_free */value_copy_long0,		/* value_copy */NULL,			/* value_peek_pointer */"i",			/* collect_format */value_collect_int,	/* collect_value */"p",			/* lcopy_format */value_lcopy_char,		/* lcopy_value */};info.value_table = &value_table;type = g_type_register_fundamental (G_TYPE_CHAR, g_intern_static_string ("gchar"), &info, &finfo, 0);g_assert (type == G_TYPE_CHAR);type = g_type_register_fundamental (G_TYPE_UCHAR, g_intern_static_string ("guchar"), &info, &finfo, 0);g_assert (type == G_TYPE_UCHAR);}
...
}

问题来了,不能实例化的类型有啥用?通常,它们需要与GValue一起使用。GValue在初始化时,通常都需要整数或者字符串。这点可以从GValue的定义看出来。

struct _GValue
{/*< private >*/GType		g_type;/* public for GTypeValueTable methods */union {gint	v_int;guint	v_uint;glong	v_long;gulong	v_ulong;gint64      v_int64;guint64     v_uint64;gfloat	v_float;gdouble	v_double;gpointer	v_pointer;} data[2];
};

Instantiatable classed types: objects

通过类进行注册并能被实例化的类型,看起来最像是一个对象。尽管GObject是其中最为人所知的,然而,其他种类的与GObject类似的,能用作继承结构基类的对象,也已经被开发出来。这些对象有共同的基础特性。

下面举例说明如何注册此类的对象类型。

typedef struct {GObject parent_instance;/* instance members */char *filename;
} ViewerFile;typedef struct {GObjectClass parent_class;/* class members *//* the first is public, pure and virtual */void (*open)  (ViewerFile  *self,GError     **error);/* the second is public and virtual */void (*close) (ViewerFile  *self,GError     **error);
} ViewerFileClass;#define VIEWER_TYPE_FILE (viewer_file_get_type ())GType
viewer_file_get_type (void)
{static GType type = 0;if (type == 0) {const GTypeInfo info = {.class_size = sizeof (ViewerFileClass),.base_init = NULL,.base_finalize = NULL,.class_init = (GClassInitFunc) viewer_file_class_init,.class_finalize = NULL,.class_data = NULL,.instance_size = sizeof (ViewerFile),.n_preallocs = 0,.instance_init = (GInstanceInitFunc) viewer_file_init,};type = g_type_register_static (G_TYPE_OBJECT,"ViewerFile",&info, 0);}return type;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/854393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据之flink与hive

其实吧我不太想写flink&#xff0c;因为线上经验确实不多&#xff0c;这也是我需要补的地方&#xff0c;没有条件创造条件&#xff0c;先来一篇吧 flink&#xff1a; 高性能 低延迟 流批一体的分布式计算框架 基于事件时间 对实时数据精准处理 快速响应 支持批处理&#xff0c…

腾讯云点播ugc upload | lack signature 问题处理

我犯一个很傻的错误 参考腾讯云官方文档&#xff1a;云点播 Web 端上传 SDK-开发指南-文档中心-腾讯云 进行开发&#xff0c;但是却报错了&#xff0c;始终找不到问题&#xff0c;错误提示&#xff1a;ugc upload | lack signature&#xff0c;意思是缺少签名或者签名失败&…

Python基础用法 之 转义字符

将两个字符进⾏转义 表示⼀个特殊的字符 \n ---> 换⾏&#xff0c;回⻋ \t ---> 制表符, tab键 注意&#xff1a; print( end\n)&#xff1a; print() 函数中默认有⼀个 end\n, 所以,每个 print 结束之后, 都会输出⼀ 个换行。 未完待续。

HTML中的资源提示关键词

渲染阻塞问题 之前在学习浏览器的渲染原理的时候我们就知道&#xff1a;因为浏览器一次只能开启一个渲染主线程&#xff0c;所以当浏览器解析到script标签时会停止DOM树的构建&#xff0c;转而去执行script&#xff0c;如果script中引用的是外部脚本&#xff0c;则浏览器会先从…

MySQL Server和Server启动程序(一)

MySQL Server mysqld&#xff0c;也称为MySQL Server&#xff0c;是一个单线程多任务的程序&#xff0c;它在MySQL安装中执行大部分工作。它不会生成额外的进程。MySQL Server管理对包含数据库和表的MySQL数据目录的访问。数据目录也是其他信息&#xff08;如日志文件和状态文…

目标检测:NMS代码

非极大值抑制NMS是目标检测常用的后处理算法&#xff0c;用于剔除冗余检测框 总体概要&#xff1a; 对NMS进行分类&#xff0c;大致可分为以下六种&#xff0c;这里是依据它们在各自论文中的核心论点进行分类&#xff0c;这些算法可以同时属于多种类别。 分类优先&#xff1a;…

基于mysqlbinlog恢复数据

1、把binlog转换为SQL mysqlbinlog --base64-outputdecode-rows -vv /usr/local/mysql/log-bin/mysql-bin.000003 >result.sql find / -name result.sql 2、查看events show binlog events in mysql-bin.000003; 3、回滚到3667那一行的数据 mysqlbinlog -v /usr/local/mys…

Linux中手动配置Java jdk17环境

1、下载jdk二进制文件 点击官网地址&#xff1a;jdk-17_linux-x64_bin.tar.gz 或者使用wget下载 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz -P /usr/local/src/2、解压文件 tar zxvf jdk-17_linux-x64_bin.tar.gz3、修改配置 打开文件…

专业学习|博弈论-课程沿革

学习来源&#xff1a;北京大学刘霖《博弈论》MOOC公开课 备注&#xff1a;仅做学习分享&#xff0c;请勿转载&#xff0c;转载必究&#xff01; &#xff08;一&#xff09;博弈论的预备知识 基本的微积分的知识和概率论的知识。简单的说会求导数&#xff0c;会求简单的积分&am…

消息队列-Rabbit运行机制

Producer(生产者) 和 Consumer(消费者) Producer(生产者) :生产消息的一方&#xff08;邮件投递者&#xff09;Consumer(消费者) :消费消息的一方&#xff08;邮件收件人&#xff09; 消息一般由 2 部分组成&#xff1a;消息头&#xff08;或者说是标签 Label&#xff09;和 …

【已解决】chrome视频无法自动播放的问题

问题&#xff1a; 在用datav开发大屏的时候&#xff0c;放了一个视频组件&#xff0c;但是发现视频组件即使设置了自动播放&#xff0c;仍然无法自动播放 原因&#xff1a; 76 以上版本的谷歌浏览器只能在系统静音下自动播放 解决&#xff1a; 音频自动播放浏览器白名单设置&…

kafka在windows上的启动

启动zookeeper 解压kafka安装包到对应目录下&#xff0c;找到对应config目录下的zookeeper.properties文件 新建一个data文件夹&#xff0c;随便放哪 打开该文件&#xff0c;找到 dataDir/tmp/zookeeper 属性 将原来的属性值&#xff0c;修改为新建data文件夹地址&#xff0c;…

如何修改倍福CX7000PLC IP地址

我们可以通过登录网页修改PLC的IP地址,这个需要我们知道PLC的初始IP地址 1、浏览器直接输入PLC 的IP地址 2、点击修改按钮(就是那个旋转) 修改IP地址前DHCP要先disable关闭 。 3、DHCP关闭 4、点击保存 5、在CAT3里搜索 在SYSTEM双击,之后点击搜索,具体过程可以参考下…

【html】如何利用id选择器实现主题切换

今天给大家介绍一种方法来实现主题切换的效果 效果图&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initia…

充电学习—5、healthed 电池服务

1、healthed服务监听接收内核kernel的电池事件&#xff0c;然后上传数据给framware层的batterysevice&#xff0c;BatteryService计算电池的电量&#xff0c;显示&#xff0c;绘制动画等 android电池系统框架&#xff1a; 2、healthd服务入口&#xff1a;android/system/cor…

2024年设计、数字化技术与新闻传播国际学术会议(ICDDTJ 2024)

2024年设计、数字化技术与新闻传播国际学术会议(ICDDTJ 2024) 2024 International Conference on Design, Digital Technology and Journalism 会议地点&#xff1a;哈尔滨&#xff0c;中国 网址&#xff1a;www.icddtj.com 邮箱: icddtjsub-conf.com 投稿主题请注明:ICDD…

python之Bible快速检索器

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! python之Bible快速检索器 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; 助力快…

CSS入门基础2

目录 1.标签类型 2.块元素 3.行内元素 4.行内块元素 5.标签行内转换 6.背景样式 1.标签类型 标签以什么方式进行显示&#xff0c;比如div 自己占一行&#xff0c; 比如span 一行可以放很多个HTML标签一般分为块标签和行内标签两种类型&#xff1a; 块元素行内元素。 2.块…

数据结构进阶——AVL树

数据结构进阶——AVL树 0. 前言1. AVL树的概念2. AVL树节点&#xff0c;和树的定义3. AVL树的插入4. AVL树的旋转5. AVL树的验证6. AVL树的删除&#xff08;了解&#xff09;7. AVL树实现完整代码8. AVL树的性能 0. 前言 学习本章&#xff0c;需要大家先掌握搜索二叉树&#xf…

「6.18福利」精选大厂真题|笔试刷题陪伴|明天正式开屋啦 - 打卡赢价值288元丰厚奖励

&#x1f370;关于清隆学长 大家好&#xff0c;我是清隆&#xff0c;拥有ACM区域赛 银牌&#x1f948;&#xff0c;CCCC天梯赛 国一&#xff0c;PTA甲级 98 分。 致力于算法竞赛和算法教育已有 3 年&#xff0c;曾多次 AK 互联网大厂笔试&#xff0c;大厂实习经验丰富。 打卡…