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

D-Bus如何创建和发送Dict?,c,ipc,dbus,C,Ipc,Dbus,我有一个进程,它向DBus公开一个方法,其中一个参数采用以下类型签名a{sv}: {String,Variant}的Dict 对于dbus\u message\u append\u args未能为此提供足够的参考。一些信息出现在中,具体如下: DICT_条目的工作方式与结构完全相同,但不是括号 它使用大括号,并且有更多的限制。限制 是:它仅作为数组元素类型出现;它正好有两个 花括号内的单个完整类型;第一首单曲 完整类型(“键”)必须是基本类型,而不是容器 类型。实现不能接受数组之外的dict条目

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

{String,Variant}的Dict

对于
dbus\u message\u append\u args
未能为此提供足够的参考。一些信息出现在中,具体如下:

DICT_条目的工作方式与结构完全相同,但不是括号 它使用大括号,并且有更多的限制。限制 是:它仅作为数组元素类型出现;它正好有两个 花括号内的单个完整类型;第一首单曲 完整类型(“键”)必须是基本类型,而不是容器 类型。实现不能接受数组之外的dict条目, 不能接受包含零个、一个或两个以上字段的dict条目, 并且不能接受带有非基本类型密钥的dict条目。口述 条目始终是一个键值对


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

type dict_entry isn't supported yet in dbus_message_append_args_valist
虽然我实际上使用的是
dbus\u message\u append\u args
(我猜错误消息有点不正确)

对于
dbus\u message\u append\u args()
,还有两种替代方法:

dbus\u message\u iter\u append\u basic()
dbus\u message\u iter\u append\u fixed\u 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);

两个append方法似乎都不支持添加结构。不确定在这里尝试什么…

首先,关于D-Bus库:您在几个地方谈到了dbus glib,但您提到的函数不是dbus glib的一部分,而是libdbus。如果您仍在试图找到使用D-Bus的最佳方法,我建议您忘记这两个:libdbus是非常低级的(它的文档甚至以“如果您直接使用这个低级API,那么您注册会有一些麻烦”开头),dbus glib是不推荐的。目前最好的D-BusAPI是GDBus,它是的一部分:它是一个比其他两个都好得多的API,经过良好的测试和支持

现在,对于实际问题,
dbus\u message\u append\u args()
的文档非常清楚地说明了这一点:

若要附加可变长度基本类型或任何更复杂的值,请 必须使用迭代器而不是此函数

换句话说,您应该使用
dbus\u message\u iter\u open\u container()
来准备迭代器,直到它指向可以使用
dbus\u message\u iter\u append\u basic()的地方为止。请注意,在您的示例中,字典是一个容器,字典条目是一个容器,变量是一个容器。。。换句话说,它变得相当复杂,相当快。如果您确实想这样做,请查看示例代码

正如我提到的,明智的路线是GDBus。创建更复杂的签名非常简单,因为您可以使用GVariantBuilder API:

GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE("a{sv}"));
g_variant_builder_add (&builder, "{sv}", "name1", my_variant);

/* Now use the builder results with g_dbus_connection_call()
   or g_dbus_proxy_call() */

谢谢,我更新了我的问题。你是说我可以通过几个
dbus\u message\u iter\u append\u basic()
调用来模拟添加结构?低级别api的另一个原因是我希望它能够在没有依赖项的情况下工作。dict条目是DBUS_type_dict_entry类型的容器。用迭代器打开它,附加内容,然后关闭容器。关于GLib/GIO依赖性:我无法想象避免GLib(当它提供您想要的API时)是一个明智的选择。成本确实很低,但它非常有用。甚至官方的D-Bus教程也同意我的观点:“D-Bus推荐的GlibAPI是GDBus。”你能在回答中添加你描述的代码吗?我没有获得正确的行为——文档也没有提供示例。对不起,我想我没有那么投入。。。我已经好几年没有和libdbus合作了,现在有了更好的选择,我不打算回去了。但看看我链接到的Connman代码:它的质量很高,而且它们使用的方法签名非常复杂,足以显示许多不同的东西。