2011年3月29日 星期二

如何用dbus傳送array of struct (2)

 


上一篇文章中提到,可以利用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_stringg_value_get_int的函式,轉成string或int。


如何用dbus傳送array of struct

大部份dbus在傳送的資料型態,都是G_TYPE_INT、G_TYPE_STRING等簡單型態,


但如果要傳的資料型態,是一個struct的陣列 (array of struct)呢?


GTYPE並沒有適合的型態可以用,所以要做一些轉換,其中一個方法就是把array of struct轉成array of array of byte


聽起來像饒口令,但其實就是把struct轉成array of byte而已。


 


首先,xml檔要定義這個array of array of byte


<?xml version="1.0" encoding="UTF-8" ?>
<node name="/">
  <interface name="myInterface">
    <method name="myMethod">
        <arg name="myData" type="aay" />
    </method>
  </interface>
</node>


在這裡指定myData的型態為aay,就是array of (array of byte)。


 


接著,client端要送的話,要先定義好你要的struct:


typedef struct{
        gchar *title;
        gint price;
}BookInfo;


然後建立一個GPtrArray,用來裝許多個BookInfo,


GPtrArray *book_array = g_ptr_array_new();


BookInfo *book1 = (BookInfo *)g_new0(BookInfo, 1);     //建立第一本書的資訊
book1->title = g_strdup("Harry Poter");
book1->price = 199;
g_ptr_array_add(book_array, book1);   //把第一本書裝進book_array

BookInfo *book2 = (BookInfo *)g_new0(BookInfo, 1);    //建立第二本書的資訊
book2->title = g_strdup("The Da Vinci Code");
book2->price = 299;
g_ptr_array_add(book_array, book2);   //把第二本書裝進book_array


在這裡就是用g_ptr_array_add來把BookInfo裝進book_array。


 


最後要送出dbus:


dbus_g_proxy_call (proxy, "myMethod", &error,
  dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_UCHAR_ARRAY), book_array,
G_TYPE_INVALID,
G_TYPE_INVALID)


這邊需要用dbus_g_type_get_collection的函式來指定book_array的型態。


 


而在server端,收到array of array of byte,也就是GPtrArray之後,要把它還原成原來的資料:


// server端也要知道BookInfo的struct是什麼


typedef struct{
        gchar *title;
        gint price;
}BookInfo;


 


// server端接收的function


gboolean test_obj_my_method (TestObj *obj, GPtrArray *array, GError **error)
{

        for(i=0;i<array->len;i++){
                BookInfo *book = (BookInfo *)g_new0(Booknfo, 1);
                book = (BookInfo *)g_ptr_array_index(array, i);
                printf("title=%s, price=%d\n", book->title, book->price);
        }

        return TRUE;
}


接收端一樣要用GPtrArray來接,接到之後先建立BookInfo,然後用g_ptr_array_index的函式,來把第i個元素拿出來,存入BookInfo裡面。


2011年3月14日 星期一

咻咻一族

前幾天坐捷運時,人潮剛好不多。有一對情侶上來,就坐在我對面那排,整個空空的椅子,就坐著他們倆。


好玩的是,這對情侶一坐定位,就各自拿出手機來玩了!


女生是拿白色、黑生是拿黑色,似乎是iPhone,


然後就各自投入"咻咻咻"的世界了!


(什麼是咻咻咻呢? 就是觸控式手機,用一根手指頭在那滑來滑去,咻咻咻的換頁)


 


一連經過了好幾站,這對情侶除了坐在一起之外,完全沒有任何交集,也沒有任何對話。


唯一兩人有互動的,是那個女生問男生:這個要怎麼用?


還是咻咻咻的問題啊…


如果不是兩個剛上車時的親膩舉動,真的讓人完全看不出他們是一對情侶。


想較之下,另一對國中生情侶,一上來就在小聲聊天,後來小女生累了,直接頭靠在小男生肩上睡,這倒是真實多了!


 


後來到了某一站,兩個人都默默的站了起來,眼睛仍然停留在手機的畫面,然後又一起下車了。


 


最近發現咻咻一族變得愈來愈多,除了在捷運、火車上,在等車時、走路時、坐電梯時、甚至跟朋友吃飯時,


總是有人低著頭,拿著手機,手指忙著咻咻咻。


彷彿整個世界都是彈指之間,那個小小的視窗裡,彷彿裡面才是真實的世界…。


 


究竟,是人在玩手機,還是手機在玩人呢?


real_world.jpg 


2011年3月7日 星期一

I have a dream !

 


寫程式寫到一個境界,會莫名的亢奮,思維愈來愈快,敲打鍵盤的速度也喀啦喀啦的加速。


這時,腦中突然浮現十年前寫的一首詩:


 


國士無雙英氣發,憲行閒隱廬山下。


老者聞之亦悟然,師之逍遙身亦暇。


生也有涯知無盡,日換星移亦常法。


快哉何以仙境客,樂在望穿愁之涯。


 


這是一首藏頭詩,每句的第一個字合起來是”國憲老師生日快樂”,


是高中的時候,寫給班導師:林國憲老師的祝賀詩。


國憲老師是我三大恩師之一, (註1)


也因為有他,我有了夢想,並且在大學時完成了這些夢想!


 


國憲老師是高一的班導師,主要是教數學的,但在上課中,他時常會提到他大學時期的點點滴滴,


每次講到他參加了社區服務團,到偏遠的山上帶活動,與當地的小朋友開心的跳著舞,那種快樂的夢想;


或者講到他與師母認識的過程,騎著機車時,坐在後面的師母遞來一片牛舌餅,那種甜蜜的夢想;


對於人生豁達超然的態度,對情人的執著 (註2),遊山玩水,忘情漁樵 (註3),那種逍遙的夢想;


 


這些夢想,成為我的動力,成為我努力的目標。


於是考上雲科之後,馬上就加入社服團,在大二那年,隨著阿冠爸爸那支隊,遠征到台中深山上的達觀國小,完成了夢想;


也在大學中遇到了寶貝,騎著腳踏車帶著她到處跑,也完成了夢想;


逍遙豁達的人生觀,也讓我有了現在的成就;


 


但是研究所畢業之後,工作一年多以來,漸漸地發現,我幾乎快沒有製造夢想的能力了!?


工作的無耐,工作的現實,真正的踏入社會之後,責任愈來愈大,想要努力扛起來,卻發現只是不斷的去達成別人的期許;


達成老闆的期許、達成親友的期許、達成別人的期許,


然而,對自己的期許呢?對自己的交待呢?


 


成功不需要別人來幫我定義,同樣的,夢想也不需要別人來幫我定義。


勇於造製夢想! 勇於追尋夢想!


I have a Dream!


I have a Dream!


I have a Dream!


I have a Dream Today!  (註4)


 


 


 


 


註1: 高中是我生涯的轉捩點,因為三位老師的教學方式,讓我從原本成績平平的人,蛻變成名列前茅的人。這三位老師分別是:數學兼班級導師-林國憲、國文老師-吳慕雅、英文老師-陳佳音。


註2: 國憲老師的名言是:You are my only, 別人no touch. 


註3: 國憲老師的別名就是漁樵,靈感取自於蘇軾的赤壁賦。我所創作的小說《武林至尊傳》裡面的角色-遊山玩水漁樵子,靈感正是由國憲老師而來。


註4: 這句名言來自馬丁.路德.金 博士,史上最著名的一段演講 (http://www.youtube.com/watch?v=PbUtL_0vAJk )