c++ - 获取GVariant的内容

标签 c++ glib dbus gio

我目前尝试与 dbus 进行通信,并有一个函数,该函数将返回结构数组(string,uint32,string,string,对象路径)。我将结果存储在 GVariant 中,并打印此 GVariant 显示其中有正确的结果值。

更具描述性:我尝试获取 Systemd 的 Logind Managers ListSessions 的结果。

打印的输出是:

[('2', uint32 1000, 'nidhoegger', 'seat0', objectpath
'/org/freedesktop/login1/session/_32'), ('6', 1001, 'test', 'seat0',
'/org/freedesktop/login1/session/_36'), ('c2', 111, 'lightdm',
'seat0', '/org/freedesktop/login1/session/c2')]

我现在正在尝试使用以下方法获取循环中的每个数组元素:

for (uint32_t i = 0; i < ::g_variant_n_children(v); ++i)
{
    GVariant *child = ::g_variant_get_child_value(v, i);
}

打印 child 时我得到:

<('2', uint32 1000, 'nidhoegger', 'seat0', objectpath '/org/freedesktop/login1/session/_32')>

到目前为止一切顺利。现在我尝试通过以下方式使用 g_variant_get 获取单个项目:

gchar *id = NULL;
uint32_t uid = 0;
gchar *user = NULL;
gchar *seat = NULL;
gchar *session_path = NULL;

::g_variant_get(v, "(susso)", &id, &uid, &user, &seat, &session_path);

但它只给了我这个断言:

(process:12712): GLib-CRITICAL **: the GVariant format string '(susso)' has a type of '(susso)' but the given value has a type of 'v'

(process:12712): GLib-CRITICAL **: g_variant_get_va: assertion 'valid_format_string (format_string, !endptr, value)' failed

如果这是相关的:我生成了与 gdbus-codegen 通信的代码,并且获取该值的函数具有以下签名:

gboolean login1_manager_call_list_sessions_sync (
    Login1Manager *proxy,
    GVariant **out_unnamed_arg0,
    GCancellable *cancellable,
    GError **error);

我做错了什么?为什么它返回“v”作为值?

最佳答案

::g_variant_get(v, "(susso)", &id, &uid, &user, &seat, &session_path);

这看起来很可疑。您应该在 child 上调用它,而不是 v

以下 C 代码对我来说效果很好:

/* gcc `pkg-config --cflags --libs glib-2.0` -o test test.c */
#include <glib.h>

int
main (void)
{
  g_autoptr(GVariant) sessions = NULL;

  sessions = g_variant_new_parsed ("[('2', uint32 1000, 'nidhoegger', 'seat0', objectpath '/org/freedesktop/login1/session/_32'), ('6', 1001, 'test', 'seat0', '/org/freedesktop/login1/session/_36'), ('c2', 111, 'lightdm', 'seat0', '/org/freedesktop/login1/session/c2')]");

  for (gsize i = 0; i < g_variant_n_children (sessions); i++)
    {
      g_autoptr(GVariant) child = g_variant_get_child_value (sessions, i);
      g_message ("Child %" G_GSIZE_FORMAT ": %s", i, g_variant_get_type_string (child));

      guint32 uid;
      const gchar *id, *user, *seat, *session_path;

      g_variant_get (child, "(&su&s&s&o)", &id, &uid, &user, &seat, &session_path);

      g_message ("%s, %u, %s, %s, %s", id, uid, user, seat, session_path);
    }

  return 0;
}

它打印以下内容:

** Message: Child 0: (susso)
** Message: 2, 1000, nidhoegger, seat0, /org/freedesktop/login1/session/_32
** Message: Child 1: (susso)
** Message: 6, 1001, test, seat0, /org/freedesktop/login1/session/_36
** Message: Child 2: (susso)
** Message: c2, 111, lightdm, seat0, /org/freedesktop/login1/session/c2

关于c++ - 获取GVariant的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46726745/

相关文章:

c - 关于GThread和文件复制的问题

c++ - GDBus 自省(introspection) xml 中的多个完整类型

wireless - 如何真正使用 dbus 从 NetworkManager 获取可见 SSID 列表?

c++ - 为什么我可以定义一个函数,它的某些参数的顶级常量性不同?

C++ OOP - 丢失数据

c++ - 设计问题 : Enum or functions or something else

c - 如何正确编译和链接 gdbus 程序

c++ - 如何使用 boost::program_options 解析本身包含开关的命令行参数?

c - GArray 溢出

linux - .override 文件和用于使用 gschema 覆盖首选项的 .convert 文件之间的关系是什么?