转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd
作者联系方式:Li XianJing <xianjimli at hotmail dot com>
更新时间:2006-12-19
signal是GObject的重要特色,也是GTK+的基本支柱。它的原理其实很简单,基于订阅/发布模式,用于解耦消息的发送者和接受者。在D-BUS的帮助下,signal还可以跨进程传递(当然,这同时也让事情变得有些复杂了)。无论是使用现有对象的signal,还是实现新对象的signal,都是很简单的事,一般不会遇到什么问题。但有时几个问题搅在一起后,容易造成一些假象,让人防不胜防。最近一些同事遇到几个关于signal的问题,我花了一些时间调试,这里总结一下。
1. marshal函数实现错误。Glib只实现了极少的marshal函数,大部分情况下都要自己编写,尽管编写marshal函数不算复杂,但初学者仍然容易犯错,常见的错误是参数个数n_param_values没有包括对象自身,结果让marshal函数认为参数个数不匹配。幸运的是,glib提供了一个小工具glib-genmarshal,它可以产生marshal函数,输入是一个marshal的描述文件,输出marshal函数的实现。下面是一个描述文件的示例:
依次为返回值和参数列表。
使用示例:
glib-genmarshal --body marshal.list
2. 错误的signal ID。一个同事遇到一个奇怪的问题:在对象的成员函数内触发signal工作正常,而D-BUS的回调函数里触发signal就会失败。我想D-BUS的回调函数也是从mainloop里调过来的,都在同一个线程执行,不会有什么问题。用gdb跟踪到g_signal_emit_valist里,发现LOOKUP_SIGNAL_NODE (signal_id)返回的node并不属于当前对象,对比正常和异常两种情况,发现两者的signal_id不一样。查看相关代码,确认是两个同名的全局变量引起的问题。
3. 错误的对象。另外一个同事遇到一个更神奇的问题:在对象的成员函数内触发signal工作正常,而source的dispatch函数里触发signal就会失败,更奇怪的是默认处理函数调用正常,而通过D-BUS连接过来的客户端收不到signal。由此可见,即不是marshal函数的问题,也不是signal ID的问题。我怀疑是D-BUS传输出了错,跟踪signal_emitter_marshaller à D-BUS_connection_sendà_D-BUS_connection_send_preallocated_unlocked_no_update à_D-BUS_connection_do_iteration_unlockedàdo_writingàwritev,发现消息成功的写入socket了。
再看客户端代码,客户端是在message_queue_dispatch函数里分发D-BUS消息的,而这个函数一直没有被调用,也就是说D-BUS服务器没有把消息转发过来。猜想原因有两种,消息错误,或者目标不对。消息出错的可能性不大,也没有任何出错信息。在函数signal_emitter_marshaller里把对象的path打印出来,发现正常和异常两种情况的path不一样:原来是两个不同的对象实例。查看相关代码,确认是逻辑上的错误。
后两个问题的原因与signal没有什么关系,只是BUG的现象正好表现在signal上,加上有D-BUS这样的复杂玩意儿掺合,很容易把搞人蒙了。其实遇到这种问题不要着急,回忆一下signal的传递流程,设置几个关键检查点,如g_signal_emit_valist和signal_emitter_marshaller,很快就可以从现象追踪到本质。
~~end~~
相关推荐
在《GObject参考手册》中,我们可以找到关于GObject体系结构的全面知识。首先,GObject是基于类型系统构建的,它包含了类、对象、接口、信号和属性等面向对象编程的关键概念。GType是GObject系统的核心,它提供了一...
这个离线API手册包含了GObject框架的详细信息,对于理解并利用GObject进行软件开发至关重要。 GObject的设计基于一些关键概念: 1. **类型系统**:GObject系统拥有强大的类型系统,允许动态创建、注册和操作自定义...
Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍
The GObject base class Object instanciation Object memory management Reference count Weak References Reference counts and cycles Object properties Accessing multiple properties at once The ...
GObject系统为C语言提供了面向对象编程的支持,而这个"gobject_setup_property_demo.zip"压缩包显然提供了一个关于如何使用GObject进行属性设置的实例教程。 首先,我们要了解GObject。GObject是GObject库的基础类...
本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -> shape ->gobject 其中,square重载了shape类的info接口。
gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定 GirFFI由 Matijs van Zuijlen描述使用GObject内省存储库的GNOME的ruby 绑定。状态 特性为基于任何gobject的库创建绑定。在运行时生成绑定。为选定方法...
GObject定义了一个基础对象类型`GObject`,所有其他的对象类型都是从这个基础类型派生出来的。`GObject`包含了一些通用的方法,比如引用计数、信号机制等,这些方法对于管理对象的生命周期至关重要。 ##### 4. 信号...
avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。
gobject-2.0
GObject对象系统主要包括以下几个方面: 1. **通用类型系统**:这个系统用于注册各种类型的对象,并支持单一基类继承以及任意层次的继承结构。它还提供了对对象的组合、定制、内存管理和父子关系的支持。 2. **...
例如,`GObject`是所有GTK+和WebKitGTK+对象的基类,`g_object_new`用于创建对象实例,`g_signal_connect`用于注册信号处理函数。 **4. GLib** GLib是GTK+的基础,提供了许多低级别和高级别的实用工具,如数据结构...
4. **属性和信号**:在Python中,GObject的属性可以用`@property`装饰器和`__setattr__`方法来处理,而信号则通过`GObject.signal_new`和`GObject.signal_connect`来定义和连接。 5. **事件循环**:`GLib.MainLoop`...
液化天然气LGI是基于gobject内省的动态Lua绑定到基于GObject的库。 它允许直接从Lua使用基于GObject的库。 已获得许可的许可,请参见LICENSE文件全文。 该项目的主页位于。 LGI经过测试,并与标准Lua 5.1,Lua 5.2,...
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用