GLib中的数据类型及操作

转载: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                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
  • 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::Variant
DICT_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
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值