Using dbus_message_set_data() and dbus_message_get_data() in conjunction with dbus_connection_send_with_reply

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Jul 24 09:08:44 PDT 2015


On 24/07/15 14:45, Sahana Vadwa wrote:
> I'm new to Dbus

Before I answer your actual question, if you are new to D-Bus, perhaps
you didn't notice these sentences in the front page of the libdbus
documentation:

    This manual documents the low-level D-Bus C API. **If you use this
    low-level API directly, you're signing up for some pain.**

I would strongly recommend using a more friendly D-Bus library, such as
one of these:

* GDBus (part of Gio, shipped with GLib; C API; independent
  implementation; portable; LGPL)
* QtDBus (part of Qt; C++ API; wraps libdbus; portable; LGPL)
* sd-bus (part of systemd; C API; reimplementation; Linux-only; LGPL)

libdbus is the reference implementation. That does not imply that it's
the *best* implementation, only that it was the *first* implementation,
and is the one that was used to implement low-level infrastructure like
dbus-daemon.

> I'm trying to send a particular payload data from my
> application to dbus via |dbus_message_set_data()|with an intention to
> get the same data upon calling |dbus_message_get_data()|.

To avoid any misinterpretations: dbus_message_set_data() and
dbus_message_get_data() are about the message object in memory, not the
serializable data that can be transmitted across the bus. They are
mostly intended for language bindings like dbus-python, rather than
"normal" C API users.

>  1. Create a new dbus method call using |dbus_message_new_method_call()|
>  2. Allocate a data slot for the DbusMessage
>     using |dbus_message_allocate_data_slot()|
>  3. Set application payload using |dbus_message_set_data()|
>  4. Send method call using |dbus_connection_send_with_reply()| ///this
>     is a pending call for which I have a callback registered./

So far, you have one DBusMessage object, which is a method call. However...

>  5. Upon receiving the response for the pending call, get the data set
>     earlier using using |dbus_message_get_data()|

... the response is a separate DBusMessage object, representing a
different message. You sent a message of type METHOD_CALL; you got a
message of type METHOD_REPLY back. They are different serialized
messages travelling across the bus, and they are also different
DBusMessage objects in memory. If you attached data to the method call,
you can only get it back by inspecting the method call, and not by
inspecting the reply.

If you want to associate in-memory data with a particular
method-call/reply transaction, the usual way is to pass it to
dbus_pending_call_set_notify() as the user_data. It will come back into
your code in the DBusPendingCallNotifyFunction. This should be a
familiar pattern if you have used asynchronous functions in a library
like GLib.

Another way to achieve similar results is with
dbus_pending_call_set_data(), but as with dbus_message_set_data(), you
don't normally need that unless you are implementing a language binding
like dbus-python.

-- 
Simon McVittie
Collabora Ltd. <http://www.collabora.com/>



More information about the dbus mailing list