我有一个D总线方法,它接收一个将字符串映射到结构的字典作为输入:
<method name="myMethod">
<arg name="input_dict" type="a{s(ss)}" direction="in"/>
...
</method>
我试图使用busctl调用这样的方法,但没有成功。到目前为止,我已经尝试使用以下参数:
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 "str1" \( "str2" "str3" \)
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 str2 str3
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" str1 str2 str3
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 '(ss)' str2 str3
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 \(ss\) str2 str3
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 "ss" str2 str3
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 \"ss\" str2 str3
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 \(str2 str3\)
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a{s(ss)}" 1 str1 \(ss\) \(str2 str3\)
根据电话的不同,我得到了不同的错误:
No such method 'WakeUp' in interface 'com.verisure.cuxscored.DECT' at object path '/com/verisure/cuxscored/dect' (signature 'a{s(ss)}')
Too many parameters for signature.
因此,我的问题是:当使用busctl时,如何将参数传递给myMethod?
编辑
多亏了ukBaz的回答,我有了一个洞察力。我也有一个getter方法,我以前调用过它,得到的结果与ukBaz的有一点不同:
<method name="myGetMethod">
<arg name="output_dict" type="a{s(ss)}" direction="out"/>
...
</method>
运行busctl命令它给了我以下内容:
a(s(ss)) 1 "str1" "str2" "str3"
注意与预期解决方案的不同(a(s(ss))
而不是a{s(ss)}
,括号而不是大括号)。如果我做对了,那么输出应该被解释为包含一个字符串的结构数组,以及另一个包含两个字符串的结构。
我不太清楚为什么结果是不同的,但是我已经克服了使用吸气器的输出作为另一种方法的输入的问题:
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod `busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myGetMethod`
同样,如果我使用myGetMethod‘原样’的输出,该方法也能工作:
busctl call ${SERVICE} ${OBJECT} ${INTERFACE} myMethod "a(s(ss))" 1 "str1" "str2" "str3"
因此,剩下的唯一问题是,为什么D总线方法返回一个结构数组,即使它被声明为返回字典。
编辑2
如果我进行dbusctl内省,这就是我得到的:
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
${INTERFACE} interface - - -
.myGetMethod method - a{s(ss)} -
.myMethod method a{s(ss)} - -
...
作为一个旁白,我也尝试使用D脚,没有更好的结果。我调用了一个返回a{s(ss)}类型值的方法,D-英尺返回以下结构:
[('str1', ('str2', 'str3'))]
如果我使用相同的结构调用D脚上的myMethod,就会得到一个DBus.Error.UnknownMethod:
No '
"such method 'myMethod' in interface '${INTERFACE}' at object "
"path '${OBJECT}' (signature 'a{s(ss)}') (19)")
然而,如果我使用参数、大括号等等,我会得到不同的错误消息,但我无法使该方法正常工作。那么,在使用D英尺时,将这种论点传递给myMethod的合适方法是什么呢?
发布于 2021-07-15 15:55:50
我为自己创建了一个带有该签名的DBus服务,以测试以下内容:
from gi.repository import GLib
from pydbus import SessionBus
loop = GLib.MainLoop()
class MyDBUSService(object):
"""
<node>
<interface name='net.lew21.pydbus.ClientServerExample'>
<method name='Hello'>
<arg type='a{s(ss)}' name='response' direction='in'/>
</method>
<method name='Echo'>
<arg type='a{s(ss)}' name='response' direction='out'/>
</method>
<method name='Quit'/>
</interface>
</node>
"""
def Hello(self, data):
"""Prints the data sent to it"""
for my_key in data:
print(f'key: {my_key} - Value: {data[my_key]}')
def Echo(self):
"""Sends a known string back"""
return {"str1" : ("str2", "str3")}
def Quit(self):
"""removes this object from the DBUS connection and exits"""
loop.quit()
bus = SessionBus()
bus.publish("net.lew21.pydbus.ClientServerExample", MyDBUSService())
loop.run()
在busctl
自省中给出的结论是:
$ busctl --user introspect net.lew21.pydbus.ClientServerExample /net/lew21/pydbus/ClientServerExample net.lew21.pydbus.ClientServerExample
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.Echo method - a{s(ss)} -
.Hello method a{s(ss)} - -
.Quit method - - -
Echo
的结果输出是:
$ busctl --user call net.lew21.pydbus.ClientServerExample /net/lew21/pydbus/ClientServerExample net.lew21.pydbus.ClientServerExample Echo
a{s(ss)} 1 "str1" "str2" "str3"
我使用该输出来解决如何将值放入:
$ busctl --user call net.lew21.pydbus.ClientServerExample /net/lew21/pydbus/ClientServerExample net.lew21.pydbus.ClientServerExample Hello "a{s(ss)}" 1 str str2 str3
它提供了来自Python脚本的正确输出:
$ python3 dbus_service_struct.py
key: str - Value: ('str2', 'str3')
所以我不知道为什么你的第二次尝试不起作用
为了完整起见,下面是一个在字典中发送两个值的示例:
$ busctl --user call net.lew21.pydbus.ClientServerExample /net/lew21/pydbus/ClientServerExample net.lew21.pydbus.ClientServerExample Hello 'a{s(ss)}' 2 "key1" "value1:1" "value1:2" "key2" "value2:1" "value2:1"
$ python3 dbus_service_struct.py
key: key1 - Value: ('value1:1', 'value1:2')
key: key2 - Value: ('value2:1', 'value2:1')
https://stackoverflow.com/questions/68394593
复制相似问题