在上一篇文章中提到,可以利用array of array of byte來傳送struct的陣列。
除了將struct轉成array of byte之外,還有另一個方法能做到這件事,
就是把struct轉成GValueArray。
一個struct裡面可能會有很多變數,型態各不同,有的是string,有的是int,
對應到GValueArray,就是裡面會有很多個GValue,每個GValue有它自己的GType (G_TYPE_STRING、G_TYPE_INT、G_TYPE_UINT等等)。
首先,xml檔要定義這個array of struct,例如你的struct是長這樣:
typedef struct{
gchar *title;
gint price;
}BookInfo;
那麼xml裡就可以這樣寫:
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/">
<interface name="myInterface">
<method name="myMethod">
<arg name="myData" type="a(si)" />
</method>
</interface>
</node>
其中a(si)就是array of struct,而且這個struct有兩個變數,第一個是string,第二個是int。
在client端,首先要定義這個struct:
#define G_BOOK_STRUCT (dbus_g_type_get_struct("GValueArray",G_TYPE_STRING,G_TYPE_INT,G_TYPE_INVALID))
在這裡定義一個G_BOOK_STRUCT,說明它是一個GValueArray,裡面的變數型態分別是G_TYPE_STRING跟G_TYPE_INT。
然後建立一個GPtrArray,用來裝許多個G_BOOK_STRUCT,
GPtrArray *book_array = g_ptr_array_new();
接著定義第一本書的資訊,並把它加入到book_array裡面:
GValueArray *book1;
book1 = g_value_array_new(2);
GValue title = {0}, price = {0};
g_value_init(&title, G_TYPE_STRING);
g_value_init(&price, G_TYPE_INT);
g_value_set_static_string(&title, "Harry Poter");
g_value_set_int(&price, 199);
g_valu_array_append(book1, &title);
g_valu_array_append(book1, &price);
g_ptr_array_add(book_array, book1);
這邊所做的事,就是產生一個GValueArray,裡面可以放兩個GValue,第一個的態型是G_TYPE_STRING,第二個是G_TYPE_INT,
然後把值寫進GValue,附加到GValueArray裡面。
最後一行再把GValueArray加到GPtrArray裡面,如果有很多本書,就一直重覆這一段即可。
之後client要送出dbus:
dbus_g_proxy_call (proxy, "myMethod", &error,
dbus_g_type_get_collection ("GPtrArray", G_BOOK_STRUCT), book_array,
G_TYPE_INVALID,
G_TYPE_INVALID)
這邊需要用dbus_g_type_get_collection的函式來指定book_array的型態。
而在server端要接收的function:
gboolean test_obj_my_method (TestObj *obj, GPtrArray *array, GError **error)
{
gint i;
for(i=0 ; i<array->len ; i++){
GValueArray *book = (GValueArray *)g_ptr_array_index(array, i);
GValue *title = g_value_array_get_nth(book, 0);
GValue *price = g_value_array_get_nth(book, 1);
printf("title=%s, price=%d\n", g_value_dup_string(title), g_value_get_int(price));
}
return TRUE;
}
當Server端收到GPtrArray之後,一樣透過g_ptr_array_index來取出第i個GValueArray,
用g_value_array_get_nth函式,把GValueArray的第一個元素(title,型態是string)取出來,存在GValue;
接著把GValueArray的第二個元素(price,型態是int)取出來,存在GValue;
最後再透過g_value_dup_string或g_value_get_int的函式,轉成string或int。
沒有留言:
張貼留言