2017-09-28 31 views
0

나는 응답을 구문 분석하고에 "net.connman.Manager.GetServices"다음과 같습니다 기능 :"a (oa {sv})"dbus 유형을 구문 분석하는 방법은 무엇입니까?

매우 복잡한 구조입니다
<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 (data, "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 

답변

2

dataGVariant Format Strings의 설명서에 따라 입력 GVariantIter*하지 GVariant*을 가져야한다 (당신이 g_variant_get()에 두 번째 인수로 GVariant 형식 문자열을 전달하고 있습니다).

당신은 비록 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; 
}