Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we generate abstract Qt D-Bus adaptor classes?

I'm using the qdbusxml2cpp tool to generate a D-Bus adaptor class for my D-Bus server. However, it has the following drawbacks:

  • Code is generated once, and then you're not supposed to modify it. But what if we have to make changes (see below) and then the XML changes (in a backwards compatible way, of course)?

  • It is assumed that the "adaptee" has the exact same functions and signatures as the D-Bus interface. In my case, that's not exactly true, e.g. some methods are named differently. Because the generated code uses QMetaObject::invokeMethod, this is only detected at runtime. And we can't sensibly modify the generated code if we might need to regenerate it in the future.

It would be much nicer, in my opinion, if qdbusxml2cpp would generate an abstract class, just a header, where all methods are pure virtual. Then I can write an implementation of that class that simply calls the right methods on the adaptee, without going through the Qt metatype system. This solves both problems:

  • If the XML changes, we just regenerate the header. Now the compiler will complain until we implement the new interface correctly.

  • We have the freedom to call whatever functions we like on the "adaptee" class, instead of maintaining the exact same signature as in the public D-Bus interface.

I couldn't find any tool or qdbusxml2cpp fork that does the above. Before I write it myself, are there any problems with the above approach that I might be overlooking, design-wise or technical? Perhaps limitations of the metatype system related to abstract classes or pure virtual functions?

Note that I need this to work not just with methods, but with properties and signals as well.

I've also considered writing an "intermediate" adaptor that wraps the "adaptee" and offers the exact interface that the D-Bus adaptor expects, but the D-Bus adaptor would still be using the metatype system and runtime checks. Surely we can do better.

like image 275
Thomas Avatar asked Mar 16 '18 09:03

Thomas


People also ask

What is D-Bus in Qt?

D-Bus is an Inter-Process Communication (IPC) and Remote Procedure Calling (RPC) mechanism originally developed for Linux to replace existing and competing IPC solutions with one unified protocol.

What is Qdbus?

DESCRIPTION. qdbus provides an interface to Qt-based applications communicating over D-Bus. See http://www.freedesktop.org/software/dbus/ for more information about the big picture. By default qdbus will list all service names of services that are running and you can manipulate at the moment.


1 Answers

As you've discovered, there's no way to do what you want with qdbusxml2cpp directly. Which means that we have a few options here, some that you've already listed out:

It would be much nicer, in my opinion, if qdbusxml2cpp would generate an abstract class, just a header, where all methods are pure virtual.

There doesn't seem to be anything terribly wrong with this, although some tools/IDEs may not play nicely with it. One downside to this is that whenever something changes, you would have to ensure that you update all parts of the C++ source as well, not just your header, e.g. if there is boilerplate that has to change whenever a new method is added.

Code is generated once, and then you're not supposed to modify it. But what if we have to make changes (see below) and then the XML changes (in a backwards compatible way, of course)?

Depending on how well the code generator works, I've sometimes found it easier to simply use the generated code as a starting point and then simply modifying it from there. Most of the chages are generally pretty simple.

One other option that you could do is to use a different library to do the DBus communications.

  • dbus-cxx
  • dbus-cpp
  • dbus-cplusplus

I use(and maintain) dbus-cxx; there is a tool included(dbus-cxx-xml2cpp) that generates adaptee classes that are similar to the output of qdbusxml2cpp in that the adaptee class simply calls a different class that handles the actual response. The downside is that the xml2cpp tool is not that smart, and will not always output correct code. And to use dbus-cxx in a Qt application, you need to turn off the Qt keywords. However, it does have the advantage of using templated functions, so if your signature is incorrect you will get a compile error.

Unfortunately, there isn't really a good "right" way to do this, so I'm afraid that I don't have a "Do it this way" answer.

like image 179
rm5248 Avatar answered Nov 05 '22 11:11

rm5248