Qt D-Bus 概述
D-Bus 是一种进程间通信(IPC)和远程过程调用(RPC)机制,最初是为 Linux 开发的,目的是用一种统一的协议取代现有的和相互竞争的 IPC 解决方案。它还允许系统级进程(如打印机和硬件驱动程序服务)与普通用户进程之间进行通信。
它使用一种快速的二进制消息传递协议,由于延迟低、开销小,因此适用于同机通信。其规范目前由freedesktop.org
项目定义,可供各方使用。
一般来说,通信是通过一个称为 "总线"(因此而得名)的中央服务器应用程序进行的,但也可以实现应用程序之间的直接通信。在总线上进行通信时,应用程序可以查询哪些其他应用程序和服务可用,也可以按需激活某个应用程序和服务。
总线
D-Bus 总线用于多对多通信。为此,在任何应用程序连接到总线之前,都要启动一个中央服务器。该服务器负责跟踪已连接的应用程序,并将信息从源头正确路由到目的地。
此外,D-Bus 还定义了两个众所周知的总线,即系统总线和会话总线。这些总线的特殊之处在于它们具有定义明确的语义:某些服务被定义为可在其中一个或两个总线中找到。
例如,希望查询连接到计算机的硬件设备列表的应用程序可能会与系统总线上的服务通信,而提供打开用户网络浏览器的服务可能会在会话总线上找到。
在系统总线上,你还可以找到对每个应用程序允许提供的服务的限制。因此,你可以合理地确定,如果存在某种服务,它就是由受信任的应用程序提供的。
概念
信息
在底层,应用程序通过 D-Bus 相互发送消息进行通信。消息用于传递远程过程调用以及与之相关的回复和错误。在总线上使用时,消息是有目的地的,这意味着它们只被发送给相关方,避免了 "蜂拥 "或广播造成的拥塞。
然而,一种被称为 "信号信息"(基于 Qt 信号和插槽机制的概念)的特殊信息没有预定义的目的地。由于其目的是在一对多的情况下使用,信号信息被设计为通过 "选择进入 "机制工作。
Qt D-Bus 模块将消息的底层概念完全封装为 Qt 开发人员所熟悉的更简单、面向对象的方法。在大多数情况下,开发人员无需担心发送或接收消息的问题。
服务名称
在总线上进行通信时,应用程序会获得一个所谓的 "服务名称":这是同一总线上的其他应用程序认识该应用程序的方式。服务名称由 D-Bus 总线守护进程提供,用于将信息从一个应用程序路由到另一个应用程序。与服务名类似的概念是 IP 地址和主机名:一台计算机通常只有一个 IP 地址,根据其向网络提供的服务,可能会有一个或多个与之相关的主机名。
另一方面,如果不使用总线,也就不会使用服务名称。如果我们再将其与计算机网络进行比较,这就相当于点对点网络:由于对等网络是已知的,因此无需使用主机名来查找它或它的 IP 地址。
事实上,D-Bus 服务名的格式与主机名非常相似:都是以点分隔的字母和数字序列。通常的做法甚至是根据定义该服务的组织的域名来命名服务名称。
例如,D-Bus 服务由freedesktop.org
定义,可以在总线上的服务名下找到:
org.freedesktop.DBus
对象路径
与网络主机一样,应用程序通过输出对象向其他应用程序提供特定服务。这些对象是分层组织的,就像从QObject 派生的类所具有的父子关系一样。但不同之处在于,所有对象的最终父对象都是 "根对象"。
如果我们继续类比网络服务,对象路径就相当于 URL 的路径部分:
与它们一样,D-Bus 中的对象路径也是由文件系统中的路径名组成的:它们是斜线分隔的标签,每个标签都由字母、数字和下划线字符("_")组成。它们必须始终以斜线开头,且不得以斜线结尾。
接口
接口类似于 C++ 的抽象类和 Java 的interface
关键字,它声明了调用者和被调用者之间建立的 "契约"。也就是说,它们规定了可用的方法、信号和属性的名称,以及建立通信时双方应采取的行为。
Qt 在其插件系统中使用了非常类似的机制:C++ 中的基类通过Q_DECLARE_INTERFACE() 宏与唯一标识符相关联。
事实上,D-Bus 接口名称的命名方式与 Qt 插件系统所建议的方式类似:标识符通常由定义该接口的实体的域名构成。
小抄
为便于记忆命名格式及其目的,可使用下表:
D-Bus 概念 | 类比 | 命名格式 |
---|---|---|
服务名称 | 网络主机名 | 以点分隔("看起来像主机名) |
对象路径 | URL 路径组件 | 斜线分隔("看起来像路径) |
界面 | 插件标识符 | 点分隔 |
调试
在开发使用 D-Bus 的应用程序时,有时需要查看每个应用程序通过总线发送和接收的信息。
在运行每个应用程序之前,通过设置QDBUS_DEBUG
环境变量,可以按应用程序启用该功能。例如,在D-Bus 远程控制汽车示例中,我们可以通过以下方式运行控制器和汽车,仅对汽车启用调试功能:
examples/dbus/remotecontrolledcar/controller/controller & QDBUS_DEBUG=1 examples/dbus/remotecontrolledcar/car/car &
有关信息将写入应用程序启动时的控制台。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.