GLib中的数据类型及操作

来源:互联网 发布:数据中心与云计算 编辑:程序博客网 时间:2024/06/03 18:24

转载:http://blog.csdn.net/yuanxingyang/article/details/45694161

一、DATA TYPE

  • Basic Data
[Name]  [Code in D-Bus]  [Data Type in glib]  [Data Type in libdbus-C++]BYTE         ‘y’            guchar                  unsigned char           BOOLEAN      ‘b’            gboolean                boolINT16        ‘n’            gint16                  signed shortUINT16       ‘q’            guint16                 unsigned shortINT32        ‘i’            gint                    intUINT32       ‘u’            guint                   unsigned intINT64        ‘x’            gint64                  signed long longUINT64       ‘t’            guint64                 unsigned long longDOUBLE       ‘d’            gdouble                 doubleSTRING       ‘s’            const gchar *           std::stringOBJECT_PATH  ‘o’            const gchar *           DBus::Path :public std::stringUNIX_FD      ‘h’            GVariant *              intSIGNATURE    ‘g’            const gchar *           DBus::Signature :public std::string
  • Complex Data
[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::VariantDICT_ENTRY  ‘{’ and ‘}’(Only appear after ‘a’)     Gvariant    When it is used together with ‘a’,it is                                                     represented by std::map<>

二、GLib数据操作举例

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

三、注意事项

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进行释放

0 0