Можно ли избежать ссылок на варианты glibc и утечек памяти при использовании g_variant_get?

Фон

Я использую glibc и варианты.

У меня есть сценарий, в котором я хочу получить значение глубоко внутри варианта.

Исходный вариант, changed_properties имеет формат a{sv}.

      // Example 1
/* GVariant *variant = g_variant_get_variant(
        g_variant_get_child_value(g_variant_get_child_value(changed_properties, 0), 1));
*/

GVariant *changed_property = g_variant_get_child_value(changed_properties, 0);

// Example 2
GVariant *changed_property_variant = g_variant_get_variant(g_variant_get_child_value(changed_property, 1));
// Unref only frees g_variant_get_variant

// Example 3
GVariant *changed_property_variant_child = g_variant_get_child_value(changed_property, 1);

GVariant *changed_property_variant = g_variant_get_variant(changed_property_variant_child);

// Unref the objects and let reference counter get rid of used memory
g_variant_unref(changed_property_variant);
g_variant_unref(changed_property_variant_child);

Что я понимаю

Насколько я понимаю, для извлечения (что является вариантом) я должен сначала извлечь первый из массива svсловари. В примере 3 я выполняю это при первом вызове функции g_variant_get_child_value(changed_properties, 0)после закомментированного кода в Примере 1 .

Теперь у меня остался результирующий вариант в виде. Чтобы извлечь вариант, мне еще раз нужно позвонить g_variant_get_child_value(changed_property, 1) (Где индекс 0 - строка, а индекс 1 - вариант в {sv} толковый словарь.

Проблема

Проблема возникает при вызове функций, как в Примере 1 и Примере 2 . Все ссылки на память, полученные из g_variant_get_child_value(), g_variant_get_variant(), за исключением последнего вызова, который помещает ссылку в переменную, теряются и не могут быть отменены (как в Примере 3 ).

Вопрос

Итак, мой вопрос: как добраться до глубины v и его содержимое, не создавая так много GVariant объекты и обрабатывают столько памяти через ссылки?

1 ответ

Если вам был предоставлен ключ, вы, вероятно, захотите найти определенный ключ ( a{sv} представляет собой GVariant / D-Bus представление словаря "ключ-значение").

Для этого используйте GVariantDict, что позволяет индексировать доступ по строковому ключу:

      g_auto(GVariantDict) dict = G_VARIANT_DICT_INIT (changed_properties);
guint value;
if (!g_variant_dict_lookup (&dict, "key-to-look-up", "u", &value))
  g_error ("key not found");
// value from v is now in `value`

Вам нужно будет заранее знать тип значения и передать его как строку формата (третий аргумент) в g_variant_dict_lookup().

Другие вопросы по тегам