如何从 Python 将无符号值发送到 dBus

Posted

技术标签:

【中文标题】如何从 Python 将无符号值发送到 dBus【英文标题】:How to send unsigned values to dBus from Python 【发布时间】:2019-07-03 13:45:56 【问题描述】:

我正在尝试使用 PyQt5 的 DBus 模块与 KDE PowerManagerAgent 进行交互。调用 AddInhibition 方法时,我需要将第一个参数作为 uint32(无符号整数)发送,但代码将值作为单整数整数发送。

代码使用 Python 3 编写

self.dBus = QtDBus.QDBusConnection.sessionBus()
msg = QtDBus.QDBusMessage.createMethodCall(self.dBusService, self.dBusPath,self.dBusInterface,'AddInhibition')
msg << 1 << who << reason
reply = QtDBus.QDBusReply(self.dBus.call(msg))

查看 dbus-monitor 的输出,我可以看出代码确实联系了 powermonitor,但由于第一个参数的类型为 int32,因此无法找到正确的 AddInhibition 方法

尝试调用 AddInhibition 时 dbus-monitor 的输出

呼叫

方法调用时间=1549706946.073218 sender=:1.172 -> 目的地=org.kde.Solid.PowerManagement.PolicyAgent serial=5 path=/org/kde/Solid/PowerManagement/PolicyAgent;接口=org.kde.Solid.PowerManagement.PolicyAgent;成员=添加抑制 int32 1 字符串“这” 字符串“失败”

回复

错误时间=1549706946.073536 发件人=:1.29 -> 目的地=:1.172 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=5 字符串“对象路径'/org/kde/Solid/PowerManagement/PolicyAgent'的接口'org.kde.Solid.PowerManagement.PolicyAgent'中没有这样的方法'AddInhibition'(签名'iss')”

使用 QDBusViewer 应用程序时 dbus-monitor 的输出

呼叫

方法调用时间=1549723045.320128 发件人=:1.82 -> 目的地=org.kde.Solid.PowerManagement.PolicyAgent 串行=177 路径=/org/kde/Solid/PowerManagement/PolicyAgent;接口=org.kde.Solid.PowerManagement.PolicyAgent;成员=添加抑制 uint32 1 字符串“这” 字符串“作品”

回复

方法返回时间=1549723045.320888 发件人=:1.29 -> 目的地=:1.82 序列=1370 回复序列=177 uint32 30

由于 Python 不是强类型,我如何指定参数必须输入为无符号整数?

【问题讨论】:

【参考方案1】:

您可以使用DBusArgument 类通过指定参数的QMetaType 来执行此操作。

例如,假设您想使用来自org.freedesktop.DBusRequestName 方法(请参阅the spec)。 flags 参数是一个无符号整数,所以你会遇到这个问题:

>>> from PyQt5.QtDBus import QDBusConnection, QDBusInterface
>>> sessionbus = QDBusConnection.sessionBus()
>>> iface = QDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", sessionbus)
>>> c = iface.call('RequestName', 'com.mydomain.myapp', 4)
>>> c.arguments()
['Call to RequestName has wrong args (si, expected su)\n']

所以,它说它有一个字符串和一个整数 (si),但它想要一个字符串和一个无符号整数 (su)。所以,我们将使用QDBusArgument 类并指定QMetaType.UInt

>>> from PyQt5.QtCore import QMetaType
>>> from PyQt5.QtDBus import QDBusConnection, QDBusInterface, QDBusArgument
>>> sessionbus = QDBusConnection.sessionBus()
>>> iface = QDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", sessionbus)
>>> a1 = QDBusArgument()
>>> a1.add('com.mydomain.myapp', QMetaType.QString)
>>> a2 = QDBusArgument(4, QMetaType.UInt)
>>> c = iface.call('RequestName', a1, a2)
>>> c.arguments()
[1]

既然字符串没问题,那不必是QDBusArgument。我只是想展示构造它的两种方法(使用.add() 方法和仅使用构造函数)。

【讨论】:

以上是关于如何从 Python 将无符号值发送到 dBus的主要内容,如果未能解决你的问题,请参考以下文章

如何将无符号字符数组解析为数值数据

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

套接字:将无符号字符数组从 C 传递到 JAVA

在Keil中怎样避免系统自动将无符号值改为有符号值

如何将无符号整数加载到 SIMD 中

将无符号整数存储在指针中