Returning a array of structs with dbus-glib

I was looking for an example on how to return an array of struct in a D-Bus program, and I found nothing. So here is a fast note for later reference.

This is pseudo code, just to show you how to proceed.

So you want to return a "a(si)", that's it, an array of struct containing each a string and an integer.

in your example.xml: (process with dbus-binding-tool as usual)


<node name="/com/example/Example"></node>
<interface name="com.example.Example"></interface>
<method name="getExampleArray"></method>
<arg type="a(si)" name="array" direction="out"></arg>
</method>
</interface>
</node>


in your example.c:


// you define your structure here by using get_struct
#define DBUS_STRUCT_STRING_INT (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID))

gboolean desktoptracks_get_example_array(DesktopTracks *obj, GPtrArray **stats_data, GError **error)
{
for ( each element you want to return )
{
element_string , element_int = the element you want to return

GValue *value;

value = g_new0 (GValue, 1);
g_value_init (value, DBUS_STRUCT_STRING_INT);
g_value_take_boxed (value, dbus_g_type_specialized_construct (DBUS_STRUCT_STRING_INT));

// field number, value, G_MAXUINT at the end
dbus_g_type_struct_set (value, 0, element_string, 1, element_int, G_MAXUINT);
g_ptr_array_add (array, g_value_get_boxed (value));
g_free (value);
}
}


Easy uh ?

Comments

Stanislav said…
Hi,
Thanks for this article!

I Have (ss) type and I am trying to dbus_g_proxy_call() to call a method!

So I did the following:

#define G_STRUCT_STR_STR (dbus_g_type_get_struct("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID))

GValue *value;

value = g_new0 (GValue, 1);
g_value_init (value, G_STRUCT_STR_STR);
g_value_take_boxed (value, dbus_g_type_specialized_construct (G_STRUCT_STR_STR));

dbus_g_type_struct_set (value, 0, "192.168.0.1", 1, "1234", G_MAXUINT);

.....


dbus_g_proxy_call (proxy, "SetInfo", &error, G_STRUCT_STR_STR, value, G_TYPE_INVALID, G_TYPE_INVALID))

------
but I got Segmentation Fault on dbus_g_proxy_call().

Where am I wrong?

Thanks,
StanChO
Gautier Portet said…
Dear StanChO,

I really have no idea.
Marta said…
Hi!!

I read your post about returning an array of struct wih dbus-glib, I want to do a similar thing, but with a linked list instead of using an array...

Do you know I can do that or when I can find some example about send a linked list of struct on d-bus?

Thanks
Micky
Kevin said…
Thank you very much for posting this! It was very helpful.

For others to follow, here is the same sort of pseudo code for the client side to unpack the array. I can't guarantee that it's perfect, but it's a starting point:

GPtrArray *array;
service_name_get_example_array (proxy, &array, &error);

for ( i=0; i {less than} n_elements; i++)
{
GValue *value;
element_string, element_int;

value = g_new0 (GValue, 1);
g_value_init (value, DBUS_STRUCT_STRING_INT);
g_value_set_boxed (value, g_ptr_array_index (array, i));

dbus_g_type_struct_get (value, 0, &element_string, 1, &element_int, G_MAXUINT);

g_free (value);
}
Unknown said…
Do you have to allocate *stats_data in desktoptracks_get_example_array? It seems otherwise server crashes..
Gautier Portet said…
FYI, the exact source code is there: http://code.google.com/p/desktoptracks/source/browse/trunk/daemon/desktoptracksd.c
Gautier Portet said…
And yes, you have to allocate the array in this function.
sruthi mohan said…
I have a(qs(nn)q) type nested structures.
how do i define dbus_g_type_struct_get

I have defined the type as the following
#define SOURCETYPE (dbus_g_type_get_struct ("GValueArray",G_TYPE_UINT,G_TYPE_STRING,dbus_g_type_get_struct("GValueArray" ,G_TYPE_INT,G_TYPE_INT),G_TYPE_UINT,G_TYPE_INVALID))

Popular posts from this blog

Python bdist_rpm & changing the package name

Choosing a CRT-Shader for Youtube