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);

你可能感兴趣的:(GDBus (一)数据类型)