dbus-cxx
dbus-cxx Library

About

dbus-cxx is a C++ implementation of the DBus protocol. It does not use the reference C implementation of libdbus at all in order to provide a tight C++-like interface, and to fix known multithreading problems with libdbus. libsigc++ is used to help provide an OO interface to the bus. Also included is dbus-cxx-xml2cpp to generate proxy and adapter interfaces from DBus XML introspection-like documents.

Features

dbus-cxx has a number of features that gives the user a large number of ways of solving problems. Other dbus libraries that exist do not have quite the same features. The following is a list of some of the best features provided by the library:

  • Native C++ library - no C bindings required
  • Object-Oriented interface - clearly separate various concerns
  • Typesafe operations over the bus - methods and signals are declared using templates, ensuring that types are properly represented
  • Minimal boilerplate required - calling a function over the bus looks exactly like calling a local method. Methods that can be called over the bus need no special boilerplate to demarshal the data from the bus
  • Designed with thread safety in mind - methods can be called from the bus on the DBus thread or in a separate thread
  • Hooks into your existing event loop - use Qt, GLib, or libuv as your main event loop without requiring a new thread
  • Automatic introspection data generation - define your API in C++ by exporting objects, and the introspection XML will be automatically generated for you
  • Modern memory management using shared_ptr - ensures that resources are not destroyed until they are no longer being used
  • Multiple return values supported
  • dbus types are represented as standard C++ types(e.g. std::map, std::vector, std::tuple)

Easy method calling and automatic XML generation for your API

This is in my opinion the best feature of dbus-cxx, making it very easy to add methods and easily expand the API without worrying about customizing the introspection XML or defining C structs that define your API.

Let's say that we have a method that we want to export on the bus so that it can be called by another process:

double add( double param1, double param2 ) { return param1 + param2; }

This method can then be exported onto the bus with a snigle line of code(apart from standard boilerplate to setup the bus):

// ... standard boilerplate here ...
// Assume that 'Object' is of type std::shared_ptr<DBus::Object>
object->create_method<double(double,double)>("Calculator.Basic", "add", sigc::ptr_fun(add) );

Congratulations! We have now exported a method out onto the bus that can be called, and the implementation of the method is exactly the same as if it is not a method that needs to be called over the bus. Since there is no DBus-specific boilerplate code required in the method that is being called, the implementation of the function proceeeds the same no matter if the method is called from the bus or not.

When we export the object onto the bus, it is automatically introspectable. Given the above create_method call, our (summarised) introspection XML now looks like:

$ dbus-send --session --dest=dbuscxx.example.calculator.server --print-reply /dbuscxx/example/Calculator org.freedesktop.DBus.Introspectable.Introspect
method return time=1737689252.147296 sender=:1.562 -> destination=:1.563 serial=3 reply_serial=2
string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/dbuscxx/example/Calculator">
<!-- ... boilerplate here ... -->
<interface name="Calculator.Basic">
<method name="add">
<arg type="d" direction="out"/>
<arg type="d" direction="in"/>
<arg type="d" direction="in"/>
</method>
<!-- ... more methods here ... -->
</interface>
</node>
"

A similar mechanism can be used to create a proxy function - a function that when called, will in reality send a message over the DBus and wait for the return. This requires only a few lines of code to accomplish:

// ... boilerplate here ...
// Assume that `object` is of type std::shared_ptr<DBus::ObjectProxy>
DBus::MethodProxy<double(double,double)>& methodref = *(object->create_method<double(double,double)>("Calculator.Basic", "add"));
double answer;
answer = methodref( 1.0, 2.0 );
Definition: interfaceproxy.h:30

As you can see, calling the method looks exactly the same as calling a local method, without requiring the caller to marshal any data into a message or explicitly wait for a reply. Replies can always be done in an asynchronous manner, ensuring that the calling thread does not block.

While these examples show only doubles, all standard types are supported. See the DBus Types page for more information on the different types that are supported.

For more information on these examples, look in the examples/basics/methods directory.

Known Limitations

While no library is perfect, I believe that dbus-cxx fulfills the vast majority of use-cases required for DBus operation. Some known limitations are:

  • ObjectManager support may not properly deregister if you are constantly deleting/creating objects.
  • Windows is somewhat supported - some developers have succesfully used it on Windows, but this is not well supported at the moment.
  • The API does not always prevent you from doing something incorrectly
  • Variants are fully supported, but are immutable when created

Most of these limitations are generally not an issue, and most have easy workarounds. If you do run into a shortcoming, please open an issue in Github and it will be taken a look at.


Download dbus-cxx source code

NOTE: Pre-built binary packages used to be provided through a private apt server, but this is no longer the case. If you are willing to help provide packages such as this, please get in touch by using the 'discussions' tab on Github!

Releases - (.bz2, .gz, .zip) can be found on Sourceforge and Github

Source building directions

Git Repository

You can browse the git repository at this url:

https://github.com/dbus-cxx/dbus-cxx

You can also check out a copy of the repository with this command:

git clone https://github.com/dbus-cxx/dbus-cxx.git

Dependencies... and where to get them

dbus: http://dbus.freedesktop.org - Should be installed by default (runtime dependency)
libsigc++ https://github.com/libsigcplusplus/libsigcplusplus (compile dependency)
See the README file for more information on compile-time dependencies
libcppgenerate https://github.com/rm5248/libcppgenerate (compile dependency, bundled)


Documentation, Tutorials, Guides, Quick Start, et. al.

If you want to jump into the code quickly check out the quick start guide.

dbus-cxx-xml2cpp Reference Documentation on using dbus-cxx-xml2cpp to convert DBus XML introspection documents into C++ proxies and adapters.

The API documentation (including the pages you are reading now) have been generated with Doxygen.

The most current documentation for dbus-cxx is available online here:

Key sections within the API reference

Getting help

If you run into problems, you have several options for getting in touch.

Github is the best forum to initiate discussion of some issues that you may have.

  1. Github - Discussions and Issues. General help should go to the Discussions, while bugs should go to issues.
  2. Mailing lists. These are very old, but they should still work

License

dbus-cxx is released under the LGPL-3.0 and/or BSD-3-Clause