Qt D-Bus 概述
D-Bus 是一种进程间通信(IPC)和远程过程调用(RPC)机制,最初为 Linux 开发,旨在通过一种统一的协议取代现有的、相互竞争的 IPC 解决方案。它还旨在允许系统级进程(如打印机和硬件驱动程序服务)与普通用户进程之间进行通信。
它采用一种快速的二进制消息传递协议,由于其低延迟和低开销,非常适合同一台机器上的通信。其规范目前由freedesktop.org 项目定义,并向所有参与方开放。
通常情况下,通信是通过一个名为“总线”(bus,因此得名)的中央服务器应用程序进行的,但应用程序之间的直接通信也是可能的。在总线上通信时,应用程序可以查询哪些其他应用程序和服务可用,并根据需要激活其中一个。
总线
当需要实现多对多通信时,会使用 D-Bus 总线。为了实现这一目标,在任何应用程序连接到总线之前,都会先启动一个中央服务器。该服务器负责跟踪已连接的应用程序,并确保将消息从源头正确路由到目的地。
此外,D-Bus 定义了两个广为人知的总线,即系统总线和会话总线。这些总线的特殊之处在于它们具有明确定义的语义:某些服务被定义为位于其中一个或这两个总线上。
例如,一个希望查询计算机上连接的硬件设备列表的应用程序,很可能会与系统总线上提供的服务进行通信;而提供打开用户网页浏览器功能的服务,则很可能位于会话总线上。
在系统总线上,通常还会对每个应用程序允许提供的服务类型进行限制。因此,您可以相当确信:如果某个服务存在,它必定是由可信应用程序提供的。
概念
消息
在底层,应用程序通过相互发送消息在 D-Bus 上进行通信。消息用于传递远程过程调用,以及与其相关的响应和错误。在总线上使用时,消息具有目标地址,这意味着它们仅被路由到相关方,从而避免了因“蜂拥”或广播而导致的拥塞。
然而,一种称为“信号消息”(该概念基于 Qt的信号与槽机制)的特殊消息类型则没有预定义的目的地。由于其用途是在一对多的场景中使用,因此信号消息的设计采用“主动订阅”机制。
Qt D-Bus 模块将消息这一底层概念完全封装为一种更简单、且Qt开发者所熟悉的面向对象的方法。在大多数情况下,开发者无需担心消息的发送或接收。
服务名称
在总线上进行通信时,应用程序会获取所谓的“服务名称”:这是该应用程序选择让同一总线上的其他应用程序识别其身份的方式。服务名称由 D-Bus 总线守护进程进行管理,并用于将消息从一个应用程序路由到另一个应用程序。 与服务名称类似的概念是 IP 地址和主机名:一台计算机通常有一个 IP 地址,并可能根据其向网络提供的服务,关联一个或多个主机名。
另一方面,如果不使用总线,也就不会使用服务名称。如果再次将其与计算机网络进行类比,这相当于点对点网络:由于对等方是已知的,因此无需使用主机名来查找它或其 IP 地址。
实际上,D-Bus 服务名称的格式与主机名非常相似:它是由点分隔的字母和数字序列。通常的做法甚至根据定义该服务的组织的域名来命名服务名称。
例如,由freedesktop.org 定义的 D-Bus 服务,可在总线上通过以下服务名称找到:
org.freedesktop.DBus对象路径
与网络主机类似,应用程序通过导出对象向其他应用程序提供特定服务。这些对象以分层结构组织,这与从QObject 派生的类所具有的父子关系非常相似。但有一点不同,即存在“根对象”的概念,所有对象都将其作为最终父对象。
如果继续沿用 Web 服务的类比,对象路径就相当于 URL 中的路径部分:

与之类似,D-Bus 中的对象路径的构成方式与文件系统中的路径名相似:它们是由斜杠分隔的标签,每个标签由字母、数字和下划线字符(“_”)组成。它们必须始终以斜杠开头,且不能以斜杠结尾。
接口
接口类似于 C++ 的抽象类和 Java 的interface 关键字,用于声明调用方与被调用方之间建立的“契约”。也就是说,它们确定了可用的方法、信号和属性的名称,以及在建立通信时双方应遵循的行为规范。
Qt 在其插件系统中使用了非常相似的机制:C++ 中的基类通过Q_DECLARE_INTERFACE() 宏与一个唯一的标识符相关联。
事实上,Qt 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 &有关消息的信息将写入启动该应用程序的控制台。
© 2026 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.