GObject对象系统
http://www.ibm.com/developerworks/cn/linux/l-gobject/
简单的说,GObject对象系统是一个建立在GLIB基础上的,用C语言完成的,具有跨平台特色的、灵活的、可扩展的、非常容易映射到其它语言的面向对象的框架。如果你是一个C语言的执着的追随者,你没有理由不研究一下它。
快速上手Gobject
http://blog.csdn.net/acs713/article/details/7778051
What is G-object?
Why Bother to use Gobject?
)使用面向对象的设计方法来编程。GObject仅依赖于GLib和libc,通过它可使用纯C语言设计一整套面向对象的软件模块。
)多语言交互。在为已经使用
GObject框架写好的函数库建立多语言连结时,可以很容易对应到许多语言,包括C++、Java、Ruby、Python和.NET/Mono等。GObject被设计为可以直接使用在C
程序中,也封装至其他语言。
位的整型,并调用了function_foo函数。就
如你看到的,C函数的调用由gcc实现成了本地机器码的调用(这是实现起来最快的方法)。有了gcc这个第三方,我们的代码与
机器的沟通更顺畅了!记住:GType/GObject库不仅仅是为了设计向C开发者提供面向对象的特性,也是为了透明的跨语言互通性。
做一个受欢迎的协调者
(1)找到函数所处的位置:这个意味着在C编译器编译成的二进制文件中寻找这个函数。
(2)在可执行的内存中,载入有关这个函数的相关代码。
(3)在调用这个函数前,将Python的参数转换为C兼容的参数。
(4)用正确的方式调用这个函数。
(5)将C函数的返回值转换成Python兼容的变量并将其返回至Python代码中。

来自动转换函数参数和进行函数调用在不同的运行环境之间。
GOBJECT模拟封装
在 GObject世界里,类是两个结构体的组合,一个是实例结构体,另一个是类结构体。有点绕。类、对象、实例有什么区别?可以这么理解,类-对象-实例,无非就是类型,该类型所声明的变量,变量所存储的内容。后面可以知道,类结构体初始化函数一般被调用一次,而实例结构体的初始化函数的调用次数等于对象实例化的次数。所有实例共享的数据,可保存在类结构体中,而所有对象私有的数据,则保存在实例结构体中。

GOBJCT如何模拟私有属性
C语言实现CLASS域GOBJECT支持
如何实现gobject面向对象支持呢?
很简单,我们只需要建立自己的头文件,并添加一些宏定义G_DEFINE_TYPE即可。

这样,GUPnPContext就成为了Gobject库认可的一类合法公民了,即成功的把GUpnPContextClass类所代表的type(类型)注册到了glib类型系统中,并且将成功获取到一个类型ID。
也就是说,当你设计新类时,GUPnPContext可以被考虑加进你的继承体系,同时GUPnPContext也可以被用于组合成其他的类。
进一步理解GType类型系统
G_DEFINE_TYPE宏、G_DEFINE_INTERFACE宏、g_type_register_static函数等都在GType实现。

GOBEJCT如何实现继承
GObject世界里,类是两个结构体的组合,一个是实例结构体,另一个是类结构体。
GOBJECT构造函数
多态的概念
为什么要在GOBJECT引入多态?
)Gobject为每个子类在内存中保存了一份包含成员函数指针的表. 这个表,就是我们在C++经常说到的虚方法表(vtable)。当你想调用一个虚方法时,你必须先向系统请求查找这个对象所对应的虚方法表。这张表包含了一个由函数指针组成的结构体。在调用这些函数时,需要在运行时查找合适的函数指针,这样就能允许子类覆盖这个方法,我们称之为“虚函数”。
(2) Gobject系统要求我们向它注册新声明的类型,系统同时要求我们去向它注册(对象的和类的)结构体构造和析构函数(以及其他的重要信息),这样系统就能正确的实例化我们的对象。
)Gobject系统通过枚举化所有的向它注册的类型来记录新的对象类型,并且要求所有实例化对象的第一个成员是一个指向它自己类的虚函数表的指针,每个虚函数表的第一个成员是它在系统中保存的枚举类型的数字表示。
由常用的g_object_new()想到的

它可以帮助我们最终实现类类型的定义。 。 当g_object_new从xx_xx_get_type函数那里获取类类型标识码之后,便可以进行对象实例的内存分配及属性的初始化。初始化函数在前面已有介绍。
)实现xx_xx_set_property与xx_xx_get_property函数,完成g_object_new函数“属性名-属性值”结构向Gobject子类属性的映射;
(2)在Gobject子类的类结构体初始化函数中,让Gobject基类的两个函数指针set_property与get_property分别指向xx_xx_set_property与xx_xx_get_property。
)在Gobject子类的类结构体初始化函数中,为Gobject子类安装具体对象的私有属性。
可以看出,set_property是Gobject的虚函数实现,是运行时的多态。
GOBJECT多态:将优雅展示于外界
假设我们需要一种数据类型,可以实现一个可以容纳多类型元素的链表,我想为这个链表编写一些接口,可以不依赖于任何特定的类型,并且不需要我为每种数据类型声明一个多余的函数。这种接口必然能涵盖多种类型,我们称它为GValue(Generic Value,泛型)。

要编写一个泛型的属性设置机制,我们需要一个将其参数化的方法,以及与实例结构体中的成员变量名查重的机制。从外部上看,我们希望使用C字符串来区分属性和公有API,但是内部上来说,这样做会严重的影响效率。因此我们枚举化了属性,使用索引来标识它们。
属性规格,在Glib中被称作!GParamSpec,它保存了对象的gtype,对象的属性名称,属性枚举ID,属性默认值,边界值等,类型系统用!GParamSpec来将属性的字符串
名转换为枚举的属性ID,GParamSpec也是一个能把所有东西都粘在一起的大胶水。
一个Closure是一个抽象的、通用表示的回调(callback)。它是一个包含三个对象的简单结构:
)一个函数指针(回调本身) ,原型类似于:
return_type function_callback (... , gpointeruser_data);
) user_data指针用来在调用Closure时传递到callback。
时,这个函数将被调用来释放Closure的结构。
一个GClosure提供以下简单的服务:
调用(g_closure_invoke):这就是Closure创建的目的: 它们隐藏了回调者的回调细节。
通知:相关事件的Closure通知监听者如Closure调用,Closure无效和Clsoure终结。监听者可以用注册g_closure_add_finalize_notifier(终结通知),g_closure_add_invalidate_notifier(无效通知)和g_closure_add_marshal_guards(调用通知)。
对于终结和无效事件来说,这是对等的函数(g_closure_remove_finalize_notifier和g_closure_remove_invalidate_notifier,但调用过程不是。
“一眼望穿”闭包

*指针。这个在可通过查看C语言Marshaller的实现来得到证明。

个参数为GSignalMarshaller类型,它与前面体面提到的GClosureMarshal是一个东西,都是一个函数指针。

GSignalCMarshallerc_marshaller:该参数是一个GSignalCMarshall类型的函数指针,其值反映了回调函数的返回值类型和额外参数类型(所谓“额外参数”,即指除回调函数中instance和user_data以外的参数)。
例如,g_closure_marshal_VOID_VOID说明该signal的回调函数为以下的callback类型:
typedef  void (*callback)  (gpointer instance, gpointer 
user_data);
而g_closure_marshal_VOID_POINTER则说明该signal的回调函数为以下的callback类型:
typedef void (*callback)  (gpointer instance,gpointer 
arg1, gpointeruser_data);
GTypereturn_type:该参数的值应为回调函数的返回值在GType类型系统中的ID。
guintn_params:该参数的值应为回调函数的额外参数的个数。
...:这一系列的参数的值应为回调函数的额外参数在GType类型系统中的ID,且这一系列参数中第一个参数的值为回调函数的第一个额外参数在GType类型系统中的ID,依次类推。可以认为,信号就是包含对可以连接到信号的闭包的描述和对连接到信号的闭包的调用顺序的规定的集合体。
事实上,它是用来翻译闭包的参数和返回值类型的,它将翻译的结果传递给闭包。之所以不直接调用callback或闭包,而在外面加了一层msrshal的封装,主要是方便gobjec库与其他语言的绑定。例如,我们可以写一个pyg_closure_marshal_void_string函数,其中可以调用python语言编写的“闭包”并将其计算结果传递给Gvalue容器,然后再从Gvalue容器中提取计算结果。

Gobject消息系统:Signal机制
)信号注册,主要解决信号与数据类型的关联问题
)信号连接,主要处理信号与闭包的连接问题;
)信号发射, 调用callback进行处理。
GObject对象系统的更多相关文章
- 从零构建JavaScript的对象系统
		
一.正统的类与继承 类是对象的定义,而对象是类的实例(Instance).类不可直接使用,要想使用就必须在内存上生成该类的副本,这个副本就是对象. 以Java为例: public class Grou ...
 - 深入了解Qt(二)之元对象系统(Meta-Object System)
		
深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...
 - Qt Meta Object System-元对象系统
		
研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 元对象系统 ...
 - redis object 对象系统
		
redis object对象系统 概述 redis 当中, sds字符串, adlist双向链表, dict字典, ziplist压缩链表, intset整数集合等均为底层数据结构 redis 并没有 ...
 - php object 对象系统
		
php object 对象系统 概述 本节内容仅谈论对象系统内容, 对于相关内容并不做更深一步的扩展, 相关扩展的内容会在后续补充 object 对象属于 zval 结构的一种形式 php 将所有执行 ...
 - 基于类(Java)和基于原理(JavaScript)的对象系统的比较
		
Java:面向对象编程语言,吸收了C++语言的各种优点,丢掉了C++让人头疼的多继承.指针等概念.具有功能强大和简单易用的两大特征.Java具有简单性.面向对象.分布式.健壮性.安全性.平台独立与可移 ...
 - javascript中的null,对象系统还是非对象系统?
		
1.一直以来的认知 在我学习js的过程中,爱民老师的绿皮书里将js的类型系统分成了两类: 其一是元类型系统:由typeof运算来检测 其二是对象类型系统:是元类型的object的一个分支 而null这 ...
 - JS基础:基于原型的对象系统
		
简介: 仅从设计模式的角度讲,如果我们想要创建一个对象,一种方法是先指定它的类型,然后通过这个类来创建对象,例如传统的面向对象编程语言 "C++"."Java" ...
 - [Redis] redis的设计与实现-对象系统
		
1.redis并没有直接使用前面的数据结构实现键值对数据库,而是基于数据结构创建了一个对象系统,字符串对象/列表对象/哈希对象/集合对象/有序集合对象都用到了至少一种前面的数据结构2.针对不同的使用场 ...
 
随机推荐
- cookie使用和销毁
			
一.cookie导读,理解什么是cookie 1.什么是cookie:cookie是一种能够让网站服务器把少量数据(4kb左右)存储到客户端的硬盘或内存.并且读可以取出来的一种技术. 2.当你浏览某网 ...
 - python判断一个对象是可迭代?
			
1.介绍一下如何判断一个对象是可迭代的? 通过collections模块的Iterable类型判断: >>> from collections import Iterable > ...
 - B/S、C/S模式介绍
			
1.B/S模式 B/S(Browser/Server,浏览器/服务器)方式的网络结构. ①.客户端统一采用浏览器如:Netscape和IE,通过Web浏览器向Web服务器提出请求,由Web服务器对数据 ...
 - 【Java NIO】一文了解NIO
			
Java NIO 1 背景介绍 在上一篇文章中我们介绍了Java基本IO,也就是阻塞式IO(BIO),在JDK1.4版本后推出了新的IO系统(NIO),也可以理解为非阻塞IO(Non-Blocking ...
 - 【强连通分量缩点】【DFS】【动态规划】Urozero Autumn Training Camp 2016 Day 5: NWERC-2016 Problem B. British Menu
			
有向图,不经过重复点的最长链,强连通分量大小不超过5. 每个强连通分量内部暴力预处理任意两对点之间的最长路,外面DAG上dp. 不是很好写,但是预处理完了之后,可以重构每个强连通分量内部的结构,然后整 ...
 - 1.创建spring cloud父工程和子模块
			
创建父工程 idea创建父工程 idea创建一个工程.父工程管理公共资源 添加子模块 选择添加到父工程里面spring_cloud_parent 相应的子模块添加到父工程的pom.xml文件里
 - python 实现简单的KNN算法
			
from numpy import * import operator def createDataSet(): group = array([[3,104],[2,100],[1,81],[101, ...
 - Hiho----拓扑排序
			
拓扑排序·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来. 小Ho:小Hi,你这学期有选什么课么? 小H ...
 - [典型漏洞分享]结合YS业务分析使用oauth协议的风险
			
结合YS业务分析oauth协议风险 问题描述: YS 使用QQ互联的openAPI实现QQ登录YS的功能,使用该功能需要在腾讯注册登录时的回调地址,根据oauth协议,用户的code或者access_ ...
 - HDU 4665 Unshuffle (2013多校6 1011 )
			
Unshuffle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...