概述
dbus是linux下提供跨进程服务的一套机制,类以于Android下的binder。不同的地dbus一般是基于unix domain socket或是Shared Memory Transport, named pipe等。
无论dbus底下是啥,它的效率是不如binder的。
dbus底层的transport是什么
Unix Domain Socket(UDS)
略
launchd
主要用于Mac OS X, 略。
systemd
TCP Sockets
tcp:host=127.0.0.1 or tcp:host=localhost.
DBus主要概念
Service
Service通常代表一个具体的应有,即每个应用有一个Service为了全局唯一,通常写作org.gnome.Nautilus这样的。
Object/Path
应用提供服务的路径,如果是本应用自定义的一些服务,路径就可以比较随意的写,比如说/MainWindow
, /test
等。 如果是本应用实现了其他应用定义的一些服务器接口,通常写作别的应用的路径,如/org/gnome/Nautilus。
Interface
代表一组方法。通常写作org.gnome.XXXProvider之类的。
标准接口(Standard Interfaces)
每个dbus object都要提供的接口,用于dbus manager获取关于这个object的信息。
org.freedesktop.DBus.Peer 获取object是否存活、uuid
org.freedesktop.DBus.Peer.Ping ()
org.freedesktop.DBus.Peer.GetMachineId (out STRING machine_uuid)
org.freedesktop.DBus.Introspectable
获取object提供的其他interface、method信息
org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
org.freedesktop.DBus.Properties
org.freedesktop.DBus.Properties.Get (in STRING interface_name,
in STRING property_name,
out VARIANT value);
org.freedesktop.DBus.Properties.Set (in STRING interface_name,
in STRING property_name,
in VARIANT value);
org.freedesktop.DBus.Properties.GetAll (in STRING interface_name,
out ARRAY of DICT_ENTRY<STRING,VARIANT> props);
org.freedesktop.DBus.Properties.PropertiesChanged (STRING interface_name,
ARRAY of DICT_ENTRY<STRING,VARIANT> changed_properties,
ARRAY<STRING> invalidated_properties);
org.freedesktop.DBus.ObjectManager
子对象管理
org.freedesktop.DBus.ObjectManager.GetManagedObjects (out ARRAY of DICT_ENTRY<OBJPATH,ARRAY of DICT_ENTRY<STRING,ARRAY of DICT_ENTRY<STRING,VARIANT>>> objpath_interfaces_and_properties);
org.freedesktop.DBus.ObjectManager.InterfacesAdded (OBJPATH object_path, ARRAY of DICT_ENTRY<STRING,ARRAY of DICT_ENTRY<STRING,VARIANT>> interfaces_and_properties);
org.freedesktop.DBus.ObjectManager.InterfacesRemoved (OBJPATH object_path, ARRAY<STRING> interfaces);
Method
某Interface下的一个方法,就是正常的函数。
编址
A… | is identified by a(n)… | which looks like… | and is chosen by… |
---|---|---|---|
Bus | address | unix:path=/var/run/dbus/system_bus_socket | system configuration |
Connection | bus name | :34-907 (unique) or com.mycompany.TextEditor | (well-known) D-Bus (unique) or the owning program (well-known) |
Object | path | /com/mycompany/TextFileManager | the owning program |
Interface | interface | name | org.freedesktop.Hal.Manager the owning program |
Member | member name | ListNames | the owning program |
dbus工具
qdbusviewer, gui工具,用于查看系统中的所有object, path, inteface, method
dbus-monitor, commandline工具,用于实时显示bus上的request/reply。
代码
python
- 安装dasdbus
pip3 install dasdbus
- python代码
from dasbus.connection import SessionMessageBus
bus = SessionMessageBus()
proxy = bus.get_proxy("org.gnome.Nautilus", "/org/gnome/Nautilus/SearchProvider", "org.gnome.Shell.SearchProvider2")
res=proxy.GetInitialResultSet(["home"])
print(res)
meta=proxy.GetResultMetas(res)
print(meta)
Qt
Qt有两个工具可以从xml直接生成代码,但是它不是所有的数据类型都直接,不支持的方法可以先删掉然后手动实现。
qdbuscpp2xml和qdbusxml2cpp。
在cmake中,可以用相关命令生成dbus代码:
qt_add_dbus_adaptor(GENERATED_SOURCES org.example.chat.xml chat.h ChatMainWindow)
上述命令会根据org.example.chat.xml,生成chat.h这样一个头文件,里面包括了对dbus的调用。类名为ChatMainWindow. 这是调用的qdbusxml2cpp。
qt5_add_dbus_interfaces(<VAR> dbus_spec1 [dbus_spec2 ...])
qt5_add_dbus_interface(<VAR> dbus_spec basename)
上述命令则根据xml,生成具体实现dbus服务器的类。
Gtk
Gtk也有一个工具: https://github.com/Pelagicore/gdbus-codegen-glibmm
dbus-codegen-glibmm --generate-cpp-code=${HOME}/temperature-service-example/build/generated/temperature-service
${HOME}/temperature-service-example/temperature-service.xml
它是proxy和stub一起生成的:
temperature-service_common.cpp
temperature-service_common.h
temperature-service_proxy.cpp
temperature-service_proxy.h
temperature-service_stub.cpp
temperature-service_stub.h
或
SET (CODEGEN gdbus-codegen-glibmm)
SET (INTROSPECTION_XML ${CMAKE_SOURCE_DIR}/bar.xml)
SET (GENERATED_STUB
${CMAKE_BINARY_DIR}/generated/bar_stub.cpp
${CMAKE_BINARY_DIR}/generated/bar_stub.h
${CMAKE_BINARY_DIR}/generated/bar_common.cpp
${CMAKE_BINARY_DIR}/generated/bar_common.h
)
ADD_CUSTOM_COMMAND (OUTPUT ${GENERATED_STUB}
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/generated/
COMMAND ${CODEGEN} --generate-cpp-code=${CMAKE_BINARY_DIR}/generated/bar
${INTROSPECTION_XML}
DEPENDS ${INTROSPECTION_XML}
COMMENT "Generate the stub for the test program")
kdbus是啥
kdbus是dbus的transport layer
+ bus manager
。
bus manager对应的是dbus-deamon, 用kdbus的话,dbus-deamon就不需要了。