近日我订阅的dbus邮件中老是看到有人有这样的疑问:如何用dbus-glib传递复杂的数据结构?
dbus的hacker给出的解决方法就是去用dbus_g_type_get_struct*对数据结构进行层次封装!
这是很低级的!,原因有2个:
1 dbus对数据结构的封装非常麻烦:首先把数据结构转为XML定义,然后再利用dbus_g_type_get_struct
对数据结构进行容器的嵌套,一层一层的,就像老婆婆的裹脚布一样,啰嗦。对于C/S架构,这边封装,那边还要解封装,一样麻烦。
2 不利于数据结构的变化,对于C/S结构,当初期定义的数据结构考虑不周时,后期需要修改,麻烦死了,首先修改XML,然后把封装过程再搞一遍,解封装再搞一遍,有一个地方搞错了,这个的C/S就不通了!
我以前也碰到类似的烦恼,经过一段时间的摸索,发现用GArray可以完全避开dbus繁杂的数据封装过程,直接可以在D-Bus C/S之间传递复杂的数据结构,效率还很高,并且在数据结构变化时,XML根本不用修改!很方便。
具体过程请参考我前面写的一片文章:
如何高效率的使用DBUS作client/server架构 :
http://blog.csdn.net/cuijpus/archive/2007/12/07/1922658.aspx
希望对用D-BUS的网友有些帮助。
原文如下:
Message: 2
Date: Mon, 14 Apr 2008 09:11:18 +0100
From: Rob Taylor <rob.taylor@codethink.co.uk>
Subject: Re: send a very complex stuct by dbus with dbus-glib
To: Colin Walters <walters@verbum.org>
Cc: lista dbus <dbus@lists.freedesktop.org>
Message-ID: <480311A6.5010909@codethink.co.uk>
Content-Type: text/plain; charset=UTF-8; format=flowed
Colin Walters wrote:
> On Wed, Apr 9, 2008 at 4:20 AM, ivan fernandez calvo
> <ivan.fernandez@sacnet.es> wrote:
>> Is a transcription problem the correct type is G_TYPE_UINT , The
>> objetive of the the code was only show What i want to do and in the
>> process i make a mistake.
>>
>> ?
>> <method name="methodExample">
>> <arg type="(ua(bb))" name="stcElement" direction="in" />
>> </method>
>>
>
> Hi, looking at the current code (it's been a while), it looks like
you
> need to use one of the dbus_g_type_get_struct* functions when sending
> DBus structures.
Yeah, you need to use the specialized gtype system:
http://dbus.freedesktop.org/doc/dbus-glib/dbus-glib-Specializable-GType-System.html
Rob
cuijpus: 4.16号又看到有人想用GValue做容器,这也也是复杂的,而且他也没有能走下去。
Message: 2
Date: Mon, 07 Apr 2008 11:27:07 +0200
From: ivan fernandez calvo <ivan.fernandez@sacnet.es>
Subject: Re: send a very complex stuct by dbus with dbus-glib
To: lista dbus <dbus@lists.freedesktop.org>
Message-ID: <1207560427.5831.21.camel@localhost.localdomain>
Content-Type: text/plain; charset=UTF-8
this is a reduced version of the problem that i want resolved put an
array of structs into a struct.
<method name="methodExample">
<arg type="(ua(bb))" name="stcElement" direction="in" />
</method>
GValueArray* IN_stcElement= g_value_array_new(2);
?
// boolean value
GValue *pbData = g_try_new0(GValue,1);
??g_value_init (??pbData,G_TYPE_BOOLEAN);
?g_value_set_boolean (?pbData,TRUE);
//array of struct
?GPtrArray *pArrayValues = g_ptr_array_new();
?GValueArray *pStructItem= g_value_array_new(2);
GValue *pbValue1 = g_try_new0(GValue,1);
GValue *pbValue2 = g_try_new0(GValue,1);
??g_value_init (?pbValue1,G_TYPE_BOOLEAN);
??g_value_init (?pbValue2,G_TYPE_BOOLEAN);
??g_value_set_boolean (??pbValue1,TRUE);
??g_value_set_boolean (??pbValue2,TRUE);
??g_value_array_append (?pStructItem,???pbValue1);
??g_value_array_append (?pStructItem,???pbValue2);
?g_ptr_array_add(?pArrayValues,?pStructItem);
//Gvalue container for ??a GPtrArray
?GValue *pContainer = g_try_new0(GValue,1);
?//?G_TYPE_POINTER or G_TYPE_VALUE or G_TYPE_VALUE_ARRAY
g_value_init (?pContainer,G_TYPE_POINTER);
g_value_set_boxed (?pContainer,?pArrayValues);
??g_value_array_append (?IN_stcElement,?pbData);
??g_value_array_append (?IN_stcElement,??pArrayValues);
i think that the problem is to select the correct GValue container I do
not know how is it.
On s?b, 2008-04-05 at 11:47 -0400, Colin Walters wrote:
> On Tue, Apr 1, 2008 at 10:31 AM, ivan fernandez calvo
> <ivan.fernandez@sacnet.es> wrote:
> > I am trying to send a messge with this struct
> > <method name="cambioElemento">
> > <!--
> > uint32 nData; id del data
> > string sElemento; nombre
del elemento
>
> Hi, do you think you might be able to reduce this to a smaller test
case?
--
Un Saludo
Ivan Fernandez Calvo