dbus_message_set/get_data usage
Brosseau, Vincent
vincent.brosseau at bruker.fr
Thu Dec 12 05:18:32 PST 2013
I don't use high-level DBus library, because I use DBus in an embedded linux system (on ARM9).
I tried to compile such libraries (like GDBus), but they require other libraries, which require other libraries, and so on... And in some cases I failed to build the dependencies for my target.
That's why I use only libdbus, which requires only "expat" library (XML parser). And it's not so complicated to use it as it is.
The ParameterSet struct is like this : (you're right, I was not very clear on this point)
#define MAX_COUNT 10
#define VALUE_MAX_SIZE 128
typedef struct
{
int count;
char value[MAX_COUNT][VALUE_MAX_ SIZE];
} ParameterSet;
// MAX_COUNT is the max. number of values, and VALUE_MAX_SIZE is max. string length
// ex : value[0] may contain "hello"
And as I wrote, if I use directly ¶m.value[index] (where param's type is ParameterSet) in dbus_message_iter_append_basic(), I get a "Segmentation fault".
You say that char[m][n] is not the same type as char*[n]. Why ? Arrays are pointers ([] = *), and addresses are pointers (& = *).
As far as I know, in my case ¶m.value[index] is like char** (isn't it ?), since value[index] is like char* (a string, a pointer/address to a char, an array of char), and &char* is like char** (both are memory addresses which point to "h").
dbus_message_iter_append_basic() knows that it's a string thanks to its second argument "DBUS_TYPE_STRING", then it knows that there's something else after the "h" (up to \0).
Then I don't understand why it crashes.
-----Message d'origine-----
De : dbus-bounces at lists.freedesktop.org [mailto:dbus-bounces at lists.freedesktop.org] De la part de Simon McVittie
Envoyé : jeudi 12 décembre 2013 12:18
À : dbus at lists.freedesktop.org
Objet : Re: dbus_message_set/get_data usage
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
_______________________________________________
dbus mailing list
dbus at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dbus
More information about the dbus
mailing list