Можно ли избежать ссылок на варианты 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()
.