D-Bus如何创建和发送Dict?

时间:2015-04-30 16:49:57

标签: c ipc dbus

我有一个向DBus公开方法的进程,其中一个参数采用以下类型签名a{sv}

  

{String,Variant}的词典

dbus_message_append_args的{​​{3}}未能为此提供足够的参考。有些信息会显示在The libDBus documentation中,具体为:

  

DICT_ENTRY的工作原理与结构完全相同,而不是括号   它使用花括号,它有更多的限制。限制   是:它只作为数组元素类型出现;它有两个   花括号内的单一完整类型;第一首单曲   完整类型("键")必须是基本类型而不是容器   类型。实现不能接受数组之外的dict条目,   不得接受带有零个,一个或两个以上字段的dict条目,   并且不得接受带有非基本类型键的dict条目。一个字典   条目始终是一个键值对。

在尝试附加dict时,我收到以下错误消息:

type dict_entry isn't supported yet in dbus_message_append_args_valist

虽然我实际上正在使用dbus_message_append_args(我猜错误消息有点偏离)。

dbus_message_append_args()使用其他两种方法:

dbus_message_iter_append_basic()dbus_message_iter_append_fixed_array()

虽然我可以使用以下内容创建一个空的Dict容器:

  const char * container_d_sig = "{sv}";
  DBusMessageIter iter, sub;
  dbus_message_iter_init_append(msg, &iter);
  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, container_d_sig, &sub);
  dbus_message_iter_close_container(&iter, &sub);

两种追加方法似乎都不支持添加结构。不知道在这里尝试一下......

1 个答案:

答案 0 :(得分:0)

我知道这个问题是不久前被问到的,但我最近有一个非常相似的问题,经过几个小时的反复试验,这是我想出的一些对我有用的代码。希望它可以帮助其他人...

DBusMessage* testMessage()
{
    DBusMessage* mssg = dbus_message_new_signal("/fi/w1/wpa_supplicant1/Interfaces/0", "fi.w1.wpa_supplicant1.Interface", "PropertiesChanged");

    DBusMessageIter iter, aIter;
    dbus_message_iter_init_append(mssg, &iter);
    if (!dbus_message_iter_open_container(&iter, 'a', "{sv}", &aIter))
        return nullptr;

    DBusMessageIter eIter;
    if (!dbus_message_iter_open_container(&aIter, 'e', NULL, &eIter)) {
        dbus_message_iter_abandon_container_if_open(&iter, &aIter);
        return nullptr;
    }

    const char* key = "test key";
    dbus_message_iter_append_basic(&eIter, 's', static_cast<void*>(&key));

    DBusMessageIter vIter;
    if (!dbus_message_iter_open_container(&eIter, 'v', "i", &vIter)) {
        dbus_message_iter_abandon_container_if_open(&aIter, &eIter);
        dbus_message_iter_abandon_container_if_open(&iter, &aIter);
        return nullptr;
    }

    dbus_int32_t val = 42;
    dbus_message_iter_append_basic(&vIter, 'i', static_cast<void*>(&val));

    dbus_message_iter_close_container(&eIter, &vIter);
    dbus_message_iter_close_container(&aIter, &eIter);
    dbus_message_iter_close_container(&iter, &aIter);

    return mssg;
}

这是 C++,但应该很容易适应 C。返回的消息具有 a{sv} 的签名。 The dbus docs 很有帮助。