dbus_message_set/get_data usage
Simon McVittie
simon.mcvittie at collabora.co.uk
Thu Dec 12 03:17:32 PST 2013
On 12/12/13 08:07, Brosseau, Vincent wrote:
> Now I understand that I can't attach data to the message in this way... But I'm
> not sure to understand what are dbus_message_set/get_data used for,
> exactly (your example with Python doesn't help me, sorry)...
If you don't know why you'd need them, then you don't need them; they're
for unusual situations which tend to appear when writing high-level
language bindings. They're analogous to g_object_(get|set)_data(), if
that's any help.
If in doubt, prefer to use a high-level D-Bus library like GDBus (C,
GLib/GObject, reimplements libdbus, my preferred choice) or QtDBus (C++,
Qt, wraps libdbus) rather than using libdbus directly. The libdbus
documentation does say "If you use this low-level API directly, you're
signing up for some pain".
> Anyway, I have another question about attaching parameters.
> When I use dbus_message_iter_init_append() and then dbus_message_iter_append_basic(),
> the latter needs a (void *)parameter as the third argument.
Yes, or more precisely, a pointer to a type chosen to be appropriate for
the second argument: for instance, DBUS_TYPE_INT32 -> (dbus_int32_t *),
DBUS_TYPE_STRING -> (char **).
> // param contains a field with the number of string values to attach => count
> // and an array of string values => value[MAX_COUNT]
Please be specific: if in doubt, quote actual code. Does it look like this
struct {
...
int count;
char *value[MAX_COUNT]; // of which 0..count-1 contain values
...
} param;
param.count = 2;
param.value[0] = strdup ("hello");
param.value[1] = strdup ("world");
or more like this?
struct {
...
int count;
char value[VALUE_LEN][MAX_COUNT];
} param;
param.count = 2;
strncpy (param.value[0], "hello", VALUE_LEN);
strncpy (param.value[1], "world", VALUE_LEN);
> for( int a = 0; a < param.count; a++ )
> {
> dbus_message_iter_append_basic( &dbusArg, DBUS_TYPE_STRING, ¶m.value[a] );
If the type of value is char *[n] then that should work, AFAICS:
value[a] is a char * pointing to the "h" of "hello", so &value[a] is a
char ** pointing to a char * pointing to the "h" of "hello", as required.
If the type of value is char[m][n] then value[a] is a char[m] containing
"hello", &value[a] points to the "h" of "hello", and your app crashes
when libdbus treats it as a char **, and as a result, tries to
dereference the bytes at and after the "h" as a char *.
With hindsight, either the type of the third argument should have been
const DBusBasicValue * to force the use of a suitable temporary
variable, or there should have been a family of type-safe functions like
dbus_message_iter_append_string().
> const char *arg = param.value[a];
> dbus_message_iter_append_basic( &dbusArg, DBUS_TYPE_STRING, &arg );
If in doubt, use a temporary like this, or (preferably) use a
higher-level D-Bus library. I use GDBus, when I can.
S
More information about the dbus
mailing list