GDBus (一)數據類型

一、數據類型

1、基本數據類型

Name     Code in D-Bus     Data Type in glib     Data Type in libdbus-C++
BYTE     ‘y’     guchar     unsigned char
BOOLEAN     ‘b’     gboolean     bool
INT16     ‘n’     gint16     signed short
UINT16     ‘q’     guint16     unsigned short
INT32     ‘i’     gint     int
UINT32     ‘u’     guint     unsigned int
INT64     ‘x’     gint64     signed long long
UINT64     ‘t’     guint64     unsigned long
long
DOUBLE     ‘d’     gdouble     double
STRING     ‘s’     const gchar *     std::string
OBJECT_PATH     ‘o’     const gchar *     DBus::Path :
public std::string
UNIX_FD     ‘h’     GVariant *     int
SIGNATURE     ‘g’     const gchar *     DBus::Signature :
public std::string

2、複雜數據類型

Name     Code in D-Bus     Data Type in glib     Data Type in libdbus-C++
STRUCT     ‘(‘ and ‘)’     Gvariant     DBus::Struct<>
ARRAY     ‘a’     Gvariant     std::vector<>
VARIANT     ‘v’     Gvariant     DBus::Variant
DICT_ENTRY     ‘{’ and ‘}’
(Only
appear
after ‘a’)     Gvariant     When it is used
together with ‘a’,
it is represented
by std::map<>



二、注意事項

1、GLib-CRITICAL **: g_variant_unref: assertion 'value->ref_count > 0'

出現這種錯誤是由於調用g_variant_unref()的時機不正確,無論是從client通過同步接口或異步接口調用server接口時,在org_gtk_gdbus_example_animal_call_example_sync或org_gtk_gdbus_example_animal_call_example裏面都會將GVariant的引用計數減1,有時調用以上兩個函數後立即調用g_variant_unref()可能沒有這個錯誤,估計是由於這兩個函數裏面把g_variant_unref()的處理過程放到其它線程處理,函數返回時,還沒有進行g_variant_unref()的動作;所以緊接着執行g_variant_unref()不會出現問題;如果在這兩個函數調用後sleep(20),在調用g_variant_unref(),肯定會報以上的錯誤;同樣在server端調用org_gtk_gdbus_example_animal_complete_example返回值時,也會將返回值的GVariant的引用計數減1


2、有時會出現莫名其妙的Segmentation fault錯誤

如果使用printf進行輸出log時,輸出的格式化字符串沒有\n,就會出現Segmentation fault錯誤

3、DICT_ENTRY類型最好只使用a{s*}和 a{o*}兩種

因爲當你使用g_variant_lookup進行查找時,你會發現g_variant_lookup只支持以上兩種

4、GvariantIter類型的指針使用完,要使用g_variant_iter_free進行釋放

5、GvariantBuilder類型的指針使用完,要使用g_variant_builder_unref進行釋放


三、數據類型的序列化和反序列化


1、結構體序列化

     GVariant    *pmark = NULL;

        gdouble m1 = 80;
     gdouble m2 = 70;
     const gchar * sm1 = "chinese";
     const gchar * sm2 = "english";
     pmark = g_variant_new("((sd)(sd))",sm1,m1,sm2,m2);

2、結構體反序列化

     GVariant *out_arg = NULL;
     const gchar *           subChin = NULL;
     gdouble                 markChin = 0;
     const gchar *           subEng = NULL;
     gdouble                 markEng = 0;

        g_variant_get(out_arg, "((sd)(sd))",&subChin,&markChin,&subEng,&markEng);


3、數組的序列化

      GVariantBuilder *builder = NULL;

    GVariant *outarg = NULL;

    builder = g_variant_builder_new(G_VARIANT_TYPE("a(sn)"));

    g_variant_builder_add(builder, "(sn)","test",1);

    g_variant_builder_add(builder, "(sn)","tmp",2);

      outarg = g_variant_new("a(sn)", builder);

      g_variant_builder_unref(builder);


4、數組的反序列化

    GVariantIter *iter = NULL;
    const gchar * str = NULL;
    gint16 num = 0;
    g_variant_get(argout, "a(sn)", &iter);

    while (g_variant_iter_loop(iter, "(sn)", &str,&num))
    {
        printf("return message : %s        %d\n", str,num);
    }
    g_variant_iter_free(iter);


5、鍵值對序列化

   GVariantBuilder *builder = NULL;
   GVariant *argin = NULL;

   builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));

   g_variant_builder_add(builder,"{ss}","lastdance.mp3","music/lastdance.mp3");
   g_variant_builder_add(builder,"{ss}","Madonna.mp3","music/Madonna.mp3");
   g_variant_builder_add(builder,"{ss}","DavidGarrett.mp3","music/David Garrett.mp3");
   argin = g_variant_new("a{ss}", builder);
   g_variant_builder_unref(builder);


6、鍵值對反序列化

   g_variant_lookup(arg_inarg,"lastdance.mp3","s",&str);
   printf("find keyvale:%s\n",str);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章