【问题标题】:C++: How do I load a PulseAudio module via DBUS API?C++:如何通过 DBUS API 加载 PulseAudio 模块?
【发布时间】:2014-04-25 13:54:56
【问题描述】:

PulseAudio DBUS API page 说 LoadModule 的参数是

参数:名称:字符串,参数:{String -> String}

它还指出 {String -> String} 是一个带有字符串键和字符串值的字典。

如何通过 c++ API 发送这个?通常我会这样做:

msg = dbus_message_new_method_call(
            "org.PulseAudio1",              //Destination
            "/org/pulseaudio/core1",                    //Object path to call on
            interfaceStr,                               //Interface to call on
            method);                                    //Method

然后创建一个 msg 迭代器:

//append arguments to the LoadModule() method. (String, {String->String})
dbus_message_iter_init_append(msg, &msgIter);

dbus_message_iter_append_basic(&msgIter, DBUS_TYPE_STRING,&moduleName);

//dict entries
dbus_message_iter_open_container(&msgIter, DBUS_TYPE_DICT_ENTRY, NULL, &subIter);
dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &sourceStr);
dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &sourcePath);
dbus_message_iter_close_container(&msgIter, &subIter);

dbus_message_iter_open_container(&msgIter, DBUS_TYPE_DICT_ENTRY, NULL, &subIter);
dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &sinkStr);
dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &sinkPath);
dbus_message_iter_close_container(&msgIter, &subIter);

这会创建一个像这样的参数列表,我认为:LoadModule(String, {String->String}, {String->String})

但是,该函数没有给出回复。我认为我没有正确创建参数。事实上,我很确定我不是。我见过其他人将数组用于不同的方法,但这里没有具体说明。有没有办法明确说明某物是键/值?

更新:

我发现这一行:字典条目必须是数组的元素,并且它必须只包含两个元素的键值对,具有基本的 D-Bus 类型键。 GNU Using of D-Bus Page, 以防万一。我会尝试并发布结果。

【问题讨论】:

  • 您正在尝试创建带有签名“s{ss}{ss}”的 dbus 消息,而不是预期的是“s{ss}”。 Pulse 音频客户端库已经这样做了。你可以看看它的实现以供参考。
  • 感谢@RanjitKaturi 的回复 对,因为该模块需要两个这样的字典条目:loadModule("module name", "sink"="sink/path", "source"="source/小路”)。如何使用 s{ss} 的数据结构发送所有这些?

标签: c++ dictionary dbus pulseaudio


【解决方案1】:

正如我的更新所说,dict 条目必须在数组中,但它不必是数组中的唯一元素。例如,PulseAudio 的 loopback 模块采用如下命令行参数:

$pactl load-module module-loopback source="alsa_input.pci-0000_00_1b.0.analog-stereo" sink="bluez_sink.10_B7_F6_02_1B_4A"

为了通过 DBUS 发送它,loadModule() 函数需要一个字符串和两个 dict 条目,每个条目都包含一个字符串键(“源”或“接收器”)和一个字符串值(“设备名称”)。请注意,字符串值不是我最初怀疑的设备的 PULSEAUDIO 路径。它与 pactl 使用的字符串相同。为了创建 s{ss}{ss} 参数,dict 条目首先必须封装在一个数组中:s[{ss}{ss}]。迭代器命令如下:

//append arguments to the Set() method. (string interface, string property, value)
dbus_message_iter_init_append(msg, &msgIter);

    //string
    dbus_message_iter_append_basic(&msgIter, DBUS_TYPE_STRING,&moduleName);

    //array
    dbus_message_iter_open_container(&msgIter,DBUS_TYPE_ARRAY,"{ss}{ss}",&arrayIter);

        //dict entry
        dbus_message_iter_open_container(&arrayIter, DBUS_TYPE_DICT_ENTRY, NULL, &dictIter1);
            //strings
            dbus_message_iter_append_basic(&dictIter1, DBUS_TYPE_STRING, &sourceStr);
            dbus_message_iter_append_basic(&dictIter1, DBUS_TYPE_STRING, &sourceName);
        //close dict entry
        dbus_message_iter_close_container(&arrayIter, &dictIter1);

        //dict entry
        dbus_message_iter_open_container(&arrayIter, DBUS_TYPE_DICT_ENTRY, NULL, &dictIter2);
            //strings
            dbus_message_iter_append_basic(&dictIter2, DBUS_TYPE_STRING, &sinkStr);
            dbus_message_iter_append_basic(&dictIter2, DBUS_TYPE_STRING, &sinkName);
        //close dict entry
        dbus_message_iter_close_container(&arrayIter, &dictIter2);

    //close array
    dbus_message_iter_close_container(&msgIter, &arrayIter);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 2019-07-28
    • 2016-03-27
    • 2013-08-24
    • 2017-09-15
    相关资源
    最近更新 更多