meego中dbus服务程序开发的一点总结

转载时请注明出处和作者联系方式
文章出处:
http://blog.youkuaiyun.com/jack0106
作者联系方式:冯牮
fengjian0106@yahoo.com.cn

 


     我们的项目团队之前是在moblin平台上作开发的,使用的是gobject那一套对象系统,moblin合并成meego后,考虑到新技术的学习成本和之前完成的代码的重用性,我们在meego平台上开发的时候,有一部分代码还是继续沿用原来的gobject系统,而并没有完全换用qt的对象系统。当然,这一部分继续基于gobject系统开发的代码,肯定不会是GUI部分,而主要都是一些基于dbus的中间件。

     开发过程中,发现了一个问题,我们用gobject和dbus-glib库,开发了一个dbus服务程序,其中有一个函数,它的xml定义片段如下:

    <method name="GetContacts">
      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
      <arg type="a{ss}" name="contactList" direction="out" />
    </method>
    如果dbus客户端程序,也使用dbus-glib这个库进行开发,那么,是没有任何问题的。但是,handset版的meego,主要的开发环境还是qt,而且qt里面也有dbus相关的类。而问题就在于唯一的这个参数,a{ss}。如果dbus客户端使用qtdbus接口的话,是不能正确调用到这个服务程序端的函数的。后来查了一下原因,总结了一下。

 


    dbus本身,支持的数据类型并不多,主要都是一些最基本的,比如INT,DOUBLE,STRING等等,还有少数容器类型。但是,dbus又是一个比较灵活的系统,其支持的数据类型,是可以扩充的。比如,dbus-glib库,就扩充了数据类型,qt中dbus相关的类,也有相应的数据类型扩充。问题就在于不同的对象系统,在扩充dbus数据类型的时候,并不统一(其实是不可能统一的)。上面提到的a{ss},是dbus-glib库扩充出来的一个类型,对应到glib里面,其实就是GHashTable。qt里面不可能有 GHashTable,所以,用qtdbus接口开发出来的客户端,不能成功的调用上面给出的服务端函数接口。

 


     解决办法有3个:

     1. 要求客户端使用者使用dbus-glib库提供的接口。这个方法不太合适,毕竟,meego上主要的开发环境是qt,我们不能要求第三方开发者还要掌握glib和gobject这一套系统的基本使用方法,而且,在qt程序中,使用dbus-glib接口,本身也有点四不像的感觉。

     2. 我们的服务程序,完全换用qtdbus来开发。这个方法的问题就是学习成本太大,暂时不适合我们采用。

     3. 调整参数类型。把a{ss}换成as,这样的话,虽然在处理数据的时候,不如GHashTable方便,但是仍然满足项目需求,同时,qtdbus客户端,也可以正确的调用该函数。我们项目最终采用的就是这个折衷的办法。

### Linux D-Bus 服务工作机制 D-Bus 是一种用于进程间通信 (IPC) 的消息总线系统,在 Linux 及其他类 UNIX 系统中广泛使用。它通过基于独立 Message 的传输方式简化了 IPC 过程,相比传统的方式如 PIPE 或 Socket 更加高效和易于实现[^2]。 #### 基本概念 D-Bus 提供了一个统一的消息传递接口,允许不同应用程序之间相互通信。其核心组件包括: - **Bus**: 消息的中心枢纽,负责转发消息给目标应用。 - **Service**: 注册到 Bus 上的应用程序实例,通常表示某个功能模块。 - **Object Path**: 表示 Service 中的具体对象路径,类似于文件系统的目录结构。 - **Interface**: 定义了一组方法、信号和属性,描述 Object 能够执行的操作。 - **Method Call/Signal**: 方法调用请求或事件通知。 #### 使用 QtDBus 工具进行交互 为了与现有的 D-Bus 服务进行交互,可以利用 `QtDBus` 库中的工具(例如 `qdbus`),或者直接采用命令行工具如 `dbus-send` 来发送消息并接收响应[^1]。 ##### 示例:使用 qdbus 查看可用的服务列表 ```bash qdbus --system ``` 此命令会列出当前连接至系统总线上的所有活动服务名称。 ##### 示例:调用特定 service 下的方法 假设有一个名为 `org.freedesktop.UPower` 的服务,并且该服务支持获取设备状态的功能,则可以通过如下方式进行操作: ```bash qdbus org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.DBus.Properties.Get string:"org.freedesktop.UPower" string:"DaemonVersion" ``` 上述例子展示了如何查询 UPower 守护程序版本号的信息。 #### 编写简单的客户端代码 下面是一个 Python 实现的小型 D-Bus 客户端脚本,演示了怎样访问远程对象及其提供的接口。 ```python import dbus bus = dbus.SystemBus() proxy_object = bus.get_object('org.freedesktop.UPower', '/org/freedesktop/UPower') interface = dbus.Interface(proxy_object, 'org.freedesktop.DBus.Properties') daemon_version = interface.Get('org.freedesktop.UPower', 'DaemonVersion') print(f'Daemon Version: {daemon_version}') ``` 这段代码创建了一个通往指定地址的对象代理,并通过标准属性接口检索到了守护进程的实际版本字符串。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值