Skip to content

Instantly share code, notes, and snippets.

@probonopd
Last active October 24, 2022 19:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save probonopd/72cf95947edd311f0d364b0f7d44ce6e to your computer and use it in GitHub Desktop.
Save probonopd/72cf95947edd311f0d364b0f7d44ce6e to your computer and use it in GitHub Desktop.

D-Bus, I have some questions

Every couple of months I am trying to wrap my head around D-Bus. Every time I give up, thinking it is way overcomplicated.

Maybe it is just because no one explained it in simple terms. Or maybe it is really overcomplicated.

I mean, things like MQTT are quite easy to grasp for me. But D-Bus... not.

So here are my questions.

How to make a function in a Qt application callable by other applications?

Imagine I have a class method 'doSomething()' in my Qt application. What is the minimal amount of code to make this function callable by other applications via D-Bus? Without having to do a PhD in OO design patterns first. No complicated stuff. No adaptors, no interfaces, no XML, no meta types, no similar technical mumbo jumbo please. Pseudo code: exposeOverDBus(doSomething);. Result: Other apps should see via D-Bus that this function exists and should be able to call it.

Why can't things be simple?

In Qt, do I really first need to learn what an "abstract interface class" is just so that I can make org.myproject.myapp expose myfunc via D-Bus?

Update: https://doc.qt.io/qt-6/qtdbus-pingpong-example.html makes much more sense in terms of documentation. Just ignore the QMetaObject mumbo jumbo. No XML files!

How to make a function in a Qt application callable by other applications?

Imagine the Qt application runs as a normal user, but root wants to call that function. How can that be done?

Update: https://doc.qt.io/qt-6/qtdbus-pingpong-example.html shows a relatively simple example. Just ignore the QMetaObject mumbo jumbo. No XML files!

What are the XML files for?

Qt comes with a D-Bus example called "pingpong". When 'pong' is not running, ping says The name org.example.QtDBus.PingExample was not provided by any .service files. But the example doesn't even ship any XML files! This error message is utterly misleading, since if you start pong before ping, then it works perfectly fine without any XML files at all. (This error message had lead me down a totally wrong path before, apparently!) Does it mean to say "Service org.example.QtDBus.PingExample not found on D-Bus"?

Why does D-Bus need XML files (or any files for that matter). It seems like applications can introspect D-Bus to see what applications are offering what services there. So, what are the files needed for? Imagine an application residing on external media. It just wants to offer its services to other applications via D-Bus. Does it have to install an XML file into the system first to do that? Wouldn't that kind of defeat the purpose of being able to introspect D-Bus?

Why is there dot and slash notation?

I get that D-Bus loves namespaces to avoid collissions. But why are these things sometimes separated with / and sometimes with .. If there is, say org.myproject.myapp, why isn't it sufficient to have it advertise myfunc on D-Bus, in which case other applications could see it as org.myproject.myapp, and call it with org.myproject.myapp.myfunc(params)? Why do we also need that org/myproject/myapp business in addition?

Why not just MQTT on the desktop?

Wouldn't it serve the purpose in a much simpler way? I mean, I can use it to switch my lights on and off. Why can't it just be as easy to call myfunc on my desktop?

Can we make a "Simple D-Bus" implementation?

One that would be compatible enough to be able to receive and send messages to "normal" D-Bus applications, but would be radically easier, with no XML files, automatic translation of org.myproject.myapp.myfunc to org/myproject/myapp and the other way around, etc.?

Why do we need

$ gdbus call --system \
    --dest org.freedesktop.FileManager1 \
    --object-path /org/freedesktop/FileManager1 \ 
    --method org.freedesktop.FileManager1.ShowItems \ 
     '["file:///usr"]' "" 

when all we want to say really is this:

$ dbus 'org.freedesktop.FileManager1.ShowItems("file:///usr")'

<humor>

Whoever has dreamed up D-Bus:

Your command could be improved like this:

$ gdbus call --system \
    --dest org.freedesktop.FileManager1 \
    --object-path /org/freedesktop/FileManager1 \
    --adapter org->freedesktop->FileManager1 \
    --protocol \\org\freedesktop\FileManager1 \
    --message [orgFreeDesktopFileManager1] \
    --xml '<namespace><tld>org</tld><domain>freedesktop<domain></namespace>' \
          '<application>FileManager1</application>'` \
    --method org.freedesktop.FileManager1.ShowItems \ 
     '["file:///usr"]' "" 

</humor>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment