如何解析 "a(oa{sv})" dbus 类型?
How to parse "a(oa{sv})" dbus type?
我正在解析对 "net.connman.Manager.GetServices" 函数的响应,它看起来像这样:
<method name="GetServices">
<arg name="services" type="a(oa{sv})" direction="out"/>
</method>
这是一个相当复杂的结构。
到目前为止我得到的是:
GVariant* result = ... // response containing data
GVariantIter* iter1;
g_variant_get( result, "a(oa{sv})", &iter1 );
GVariant* child = g_variant_iter_next_value( iter1 );
while ( nullptr != child )
{
gchar* string;
GVariant* data;
g_variant_get( child, "(oa{sv})", &string, &data );
// how to access inner array?
g_variant_unref( child );
child = g_variant_iter_next_value( iter1 );
}
g_variant_iter_free( iter1 );
那么,如何访问内部数组数据?
我试过这个:
GVariantIter* iter2;
g_variant_get( 数据, "a{sv}", &iter2 );
GVariant* child2 = g_variant_iter_next_value( iter2 );
但由于一些对齐错误而失败:
**
GLib:ERROR:../../glib-2.48.2/glib/gvarianttypeinfo.c:163:g_variant_type_info_check: assertion failed: (info->alignment == 0 || info->alignment == 1 || info->alignment == 3 || info->alignment == 7)
Aborted
根据 GVariant Format Strings 的文档,data
应该具有类型 GVariantIter*
,而不是 GVariant*
(您将 GVariant 格式字符串作为第二个参数传递给 g_variant_get()
).
您可以通过使用 g_variant_iter_loop()
大大简化代码:
/* Compile with: `gcc `pkg-config --cflags --libs glib-2.0 gio-2.0` -o test test.c`.
* Public domain. */
#include <glib.h>
#include <gio/gio.h>
int
main (void)
{
g_autoptr(GVariant) result = g_variant_new_parsed ("@a(oa{sv}) [('/', { 'hello': <'test'>})]");
g_autoptr(GVariantIter) iter1 = NULL;
g_variant_get (result, "a(oa{sv})", &iter1);
const gchar *string;
g_autoptr(GVariantIter) iter2 = NULL;
while (g_variant_iter_loop (iter1, "(&oa{sv})", &string, &iter2))
{
const gchar *key;
g_autoptr(GVariant) value = NULL;
while (g_variant_iter_loop (iter2, "{&sv}", &key, &value))
g_message ("%s, %s:%p", string, key, value);
}
return 0;
}
我正在解析对 "net.connman.Manager.GetServices" 函数的响应,它看起来像这样:
<method name="GetServices">
<arg name="services" type="a(oa{sv})" direction="out"/>
</method>
这是一个相当复杂的结构。
到目前为止我得到的是:
GVariant* result = ... // response containing data
GVariantIter* iter1;
g_variant_get( result, "a(oa{sv})", &iter1 );
GVariant* child = g_variant_iter_next_value( iter1 );
while ( nullptr != child )
{
gchar* string;
GVariant* data;
g_variant_get( child, "(oa{sv})", &string, &data );
// how to access inner array?
g_variant_unref( child );
child = g_variant_iter_next_value( iter1 );
}
g_variant_iter_free( iter1 );
那么,如何访问内部数组数据?
我试过这个: GVariantIter* iter2; g_variant_get( 数据, "a{sv}", &iter2 ); GVariant* child2 = g_variant_iter_next_value( iter2 );
但由于一些对齐错误而失败:
**
GLib:ERROR:../../glib-2.48.2/glib/gvarianttypeinfo.c:163:g_variant_type_info_check: assertion failed: (info->alignment == 0 || info->alignment == 1 || info->alignment == 3 || info->alignment == 7)
Aborted
data
应该具有类型 GVariantIter*
,而不是 GVariant*
(您将 GVariant 格式字符串作为第二个参数传递给 g_variant_get()
).
您可以通过使用 g_variant_iter_loop()
大大简化代码:
/* Compile with: `gcc `pkg-config --cflags --libs glib-2.0 gio-2.0` -o test test.c`.
* Public domain. */
#include <glib.h>
#include <gio/gio.h>
int
main (void)
{
g_autoptr(GVariant) result = g_variant_new_parsed ("@a(oa{sv}) [('/', { 'hello': <'test'>})]");
g_autoptr(GVariantIter) iter1 = NULL;
g_variant_get (result, "a(oa{sv})", &iter1);
const gchar *string;
g_autoptr(GVariantIter) iter2 = NULL;
while (g_variant_iter_loop (iter1, "(&oa{sv})", &string, &iter2))
{
const gchar *key;
g_autoptr(GVariant) value = NULL;
while (g_variant_iter_loop (iter2, "{&sv}", &key, &value))
g_message ("%s, %s:%p", string, key, value);
}
return 0;
}