全部博文(776)
分类: LINUX
2010-03-03 14:43:40
D-BUS分析—1 介绍 一、概述 官方网站:,但是如果要下windows版的代码最好不要从sourceforge下,多次下来的1.2.4版本都无法正常解压。可以从svn上拿,具体见后面的dbus编译部分。 从官方首页中可以看到这样一段描述D-BUS 的话:“D-Bus is a message bus system, a simple way for applications to talk to one another. In addition to interprocess communication, D-Bus helps coordinate process lifecycle; it makes it simple and reliable to code a "single instance" application or daemon, and to launch applications and daemons on demand when their services are needed. ” 因此,D-BUS从本质来说就是进程间通信(inter-process communication)(IPC)的一个实现。他最初产生于Linux平台,是做为freedesktop.org项目的一部分来开发的。正开始深 入地渗透到 Linux 桌面之中。已经在Qt4,GNOME,Windows以及Maemo实现。在KDE4中已经取代了著名的DCOP,在GNOME取代笨重的Bonobo。 在嵌入式系统中常用来实现C/S结构。 作为一个IPC,他实现了两点: 1.在同一个桌面会话中不同的应用程序进行通讯:系统总线(system bus),这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。应用程序可以直接和系统总线通信,但是发送的消息受限制。 2.桌面程序与内核或守护进程进行通讯:会话总线(Session bus),属于登录用户私有。它是用户的应用程序用来通信的一个会话总线。 二、D-BUS 特性 1.D-BUS的协议是低延迟而且低开销的,设计得小(但是代码量不算很少吧)而且高效,以便最小化传送时间。从设计上避免往返交互并允许异步操作。 2.协议是二进制的,而不是文本,这样就排除了费事的序列化过程(我们的万能参数序列化就比较占时间)。 3.考虑了字节顺序问题。 4.易用性:它按照消息而不是字节流来工作,并且自动地处理了许多困难的IPC问题,并且D-Bus库以可以封装的方式来设计,这样开发者就可以使用框架里存在的对象/类型系统,而不用学习一种新的专用于IPC的对象/类型系统。 5.请求时启动服务以及安全策略。 6.因为是做为freedesktop.org项目来开发的,有许多达人参加,所以质量应该是很有保证的。 7.支持多语言(C/C++/JAVA/C Sharp/Python/Ruby),多平台(Linux/windows/maemo)。 8.采用C语言,而不是C++。 9.由于基本上不用于internet上的IPC,因此对本地IPC进行了特别优化。 10.提供服务注册,理论上可以进行无限扩展。 三、构架 分成三层: a.libdbus库,实现了底层的API以及协议,他除了需要XML解析器以外没有必须的依赖。对于不同的语言,协议可能被重新实现。这个库是一个基 础,虽然官方说他不是设计给应用程序调用的,但是实际上应用程序是可以直接调用的,特别是windows版,后面的使用分析中的例子就能看到; b.消息守护进程,建立在libdbus的基础上,可以管理多个应用程序之间的通信。每个应用程序都和消息守护进程建立dbus链接,由消息守护进程统一进行消息的派发; c.各种包装库,绑定了一些常见的框架(qt,Glib,Java,Python,C sharp etc.)没什么新功能,只是对dbus进行了一层封装。方便使用官方建议应用程序使用这层进行调用; 体系结构图(来自网络) D-BUS分析—2 原理 一、名词解释
二、运行机制 客户端应用是请求消息的发起者。客户端应用通过和自身的相连的一个连接将请求消息发送出去,也通过该连接接收回应的消息、错误消息、系统更新消息等。在一 对一的通讯中,请求消息直接到达对象。在多对多的通讯中,请求消息先到达Dbus,Dbus将消息转发到目的对象。每个连接使用bus name来标识的,bus name有两种,一种是公共名(well-known Name),一种是唯一名(Unique Connection Name)。 所有使用D-BUS的应用程序都包含一些对象,它们一般映射为GObject、QObject、C++对象、或者[[Python">Python对象。当经由一个D-BUS连接收到一条消息时,该消息是被发往一个对象而不是整个应用程序。这一点和我们常见的消息机制是不太一样的。这个对象其实很像C++中虚函数 为了允许消息能指定接收对象,还要提供引用对象的方法。但是这个引用一般实现为与应用程序相关的内存地址,因此无法在应用程序之间传递。为了解决这一问题,D-BUS为每个对象引入名字。这些名字看起来像是文件系统路径,例如一个对象可能叫做 “/org/kde/kspread/sheets/3/cells/4/5”。路径名以容易阅读为佳,没有具体的硬性规定。 在dbus中调用一个方法包含了两条消息,进程A向进程B发送方法调用消息,进程B向进程A发送应答消息。所有的消息都由daemon进行分派,每 个调用的消息都有一个不同的序列号,返回消息包含这个序列号,以方便调用者匹配调用消息与应答消息。调用消息包含一些参数,应答消息可能包含错误标识,或 者包含方法的返回数据。 1.方法调用的一般流程: bus daemon不对消息重新排序,如果发送了两条消息到同一个进程,他们将按照发送顺序接受到。接受进程并需要按照顺序发出应答消息,例如在多线程中处理这些消息,应答消息的发出是没有顺序的。消息都有一个序列号可以与应答消息进行配对。
在dbus中一个信号包含一条信号消息,一个进程发给多个进程。也就是说,信号是单向的广播。信号可以包含一些参数,但是作为广播,它是没有返回值的。 信号触发者是不了解信号接受者的,接受者向daemon注册感兴趣的信号,注册规则是”match rules”,记录触发者名字和信号名字。daemon只向注册了这个信号的进程发送信号。 2.信号的一般流程如下: 三、将消息调用映射为本地API D-Bus的API可以把方法调用映射为特定编程语言(如C++)中的方法调用,或者把IDL中的方法调用映射为D-Bus消息。 在这些方法调用中,方法的参数被标为"in"(指明是METHOD_CALL传入参数)或者"out"(指明是METHOD_CALL的传出参 数),象CORBA的一些API具有"inout"参数,它表明该参数既传入又传出,即调用者传入的值将会被修改。映射到D-Bus上,"inout"参 数等价于"in"参数后跟着一个"out"参数,你不能在总线上传引用,所以"inout"参数完全是幻想。如果一个方法具有0个或一个返回值,后跟着0 个或多个参数,这里的每个参数可能是"in", "out"或"inout",调用者通过按顺序加上"in"或者"inout"参数来构造消息。"out"参数不会出现在调用者的消息里。接收者构造出答 复,如果有返回值,则把第一个返回加到答复上,然后按顺序加上每个"out"或"inout"参数,"in"参数不会出现在答复消息里。如果使用的语言中 有例外错误答复消息正常情况下被映射为例外。在转换本地API到D-Bus的API时,把D-Bus命名规范("FooBar")自动地映射到本地命名规 范(fooBar/foo_bar)或许好一些。只要本地API是专门写给D-Bus就行。这样当写一个对象实现且此实现将被导出到总线上是最好的了。对 象代理用于调用远程D-Bus对象,而远程D-Bus对象可能需要可以调用任何D-Bus方法的能力,因此像这样魔术般的名字映射可能是个问题。 D-BUS分析—3 编译 我们了解了什么是D-BUS了也了解了他的基本原理。精彩的是D-BUS是一个完全的opensource软件。那么是时候来看看代码了 由于dbus是支持快平台的,自然需要先考虑清楚我们想研究的目标平台。下载了linux版和windows版,其他版本没有下。 工 作环境是windows,但是最初从官方网页指引的地方下载了一个windbus,没编译过去,本来也是一般linux的东西在Windows下编译总是 一件痛苦的事情,要么借助其他第三方工具库,要么连代码都不一样。如果需要把linux porting到windows有时候也是蛮麻烦的事情,比如汇编,但是还有很多纯粹的体力劳动,比如编译器支持的语法不一样。为了能正常编译linux 版偶还特意装了一个redhat 9的虚拟机。配置就搞了半天,原因很可笑,仅仅是因为安装好vmware新增的网卡是默认使用静态IP的。很多公司都是不允许的。以前怎么一点印象都没 有。下载了1.2.4版本,但是在linux下编译没成功,正在找原因的时候发现可以通过svn下载windbus(dbus的windows版)代码。 找了一篇编译日志,稍加整理hoho编译、运行一切ok。下面是整理出来的编译dbus Windows版的步骤: 1.下载代码 通过TortoiseSVN: 2.下载并安装cmake ,安装到 将以上库都解压至 a.将windbus\tags\1.2.4拷到一个新的目录如:C:\winbus-1.2.4\source b.创建一个新的目录,用于生成sln文件以及其他需要的相关文件和目录。如:C:\winbus-1.2.4\compile c.打开CMD,进入到C:\windbus-1.2.4\complile目录,执行cmake -G "Visual Studio 8 2005" ..\windbus-1.2.4\source\cmake d.如果成功,complie目录下将生成sln文件,VS2005打开此文件即可进行编译。 注意:VS2008 用cmake -G "Visual Studio 9 2008" ..\windbus-1.2.4\source\cmake 命令,其他版本请参见cmakehelp |