gpt4 book ai didi

c++ - 如何使用结构参数从 Qt 调用 D-Bus 接口(interface)

转载 作者:行者123 更新时间:2023-12-05 05:30:13 25 4
gpt4 key购买 nike

我正在尝试向 polkit 请求授权,但我似乎无法找到如何提供结构作为参数。

QDBusArgument subject;
subject.beginStructure();
subject << "unix-process";
subject << QMap<QString, QVariant>{
{"pid", static_cast<uint32_t>(QCoreApplication::applicationPid())},
{"start-time", static_cast<uint64_t>(0)},
};
subject.endStructure();

QDBusInterface polkit("org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", "org.freedesktop.PolicyKit1.Authority");
auto result = polkit.callWithArgumentList(
QDBus::CallMode::AutoDetect,
"CheckAuthorization",
{
// how to provide the subject here?
}
);

QDBusArgument 显示了参数应该是什么样子,我需要以某种方式将其转换为可在 callWithArgumentList 中使用的格式。

FreeDesktop 这样指定结构:

{
String subject_kind,
Dict<String,Variant> subject_details
}

更具体地说,我试图用 dbus 调用替换它:

// checkProcess is *QProcess
checkProcess->start("pkcheck", {
"--process",
QString::number(QCoreApplication::applicationPid()),
"--action-id",
"my-custom-action-id",
"--allow-user-interaction"
});

最佳答案

我不太熟悉 D-Bus 或其 Qt 界面,但我碰巧有一个 linux 系统可以测试它。看来你已经在路上了,经过一些小的调整,我能够从 polkit 服务得到响应:

#include <QtDBus>

int main() {
// Not all Qt types are compatible with the D-Bus interface by default:
// QMap<QString, QVariant> is, but QMap<QString, QString> is not.
// If you need such a type, even if only to pass an empty
// Dict<String, String>, it must first be registered like so:
qDBusRegisterMetaType<QMap<QString, QString>>();

// Subject kind should be provided as a QString, integers as Qt types
QDBusArgument subject;
subject.beginStructure();
subject << QString("unix-process");
subject << QMap<QString, QVariant>{
{"pid", static_cast<quint32>(QCoreApplication::applicationPid())},
{"start-time", static_cast<quint64>(0)},
};
subject.endStructure();

// PolicyKit1 is on the system bus
QDBusInterface polkit(
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
QDBusConnection::systemBus()
);

// callWithArgumentList only takes actual QVariantLists as the arguments,
// call is a more convenient variadic function template
auto result = polkit.call(
QDBus::CallMode::AutoDetect,
"CheckAuthorization",
QVariant::fromValue(subject),
"org.freedesktop.login1.set-user-linger",
QVariant::fromValue(QMap<QString, QString>{}),
0x1u, // AllowUserInteraction = 0x00000001
""
);

qInfo() << result;
}

这导致了以下输出:

QDBusMessage(type=MethodReturn, service=":1.1", signature="(bba{ss})", contents=([Argument: (bba{ss}) false, true, [Argument: a{ss} {"polkit.retains_authorization_after_challenge" = "1"}]]) )

一些进一步的评论:

  • 在 D-Bus 类型系统中注册的类型必须可以通过 << 和 >> 运算符与 QDBusArgument 相互转换,这就是为什么在使用非 Qt 类型时会遇到问题。你可以implement these operators允许注册其他类型;
  • 传递给 D-Bus 调用的类型必须可以隐式转换为 QVariant。如果不是,您可以使用 QVariant::fromValue() 显式转换它们。

一旦满足这些要求,您应该能够从 D-Bus 获得有意义的输出,即使您传递了错误的参数。例如,省略 CheckAuthorization 的最后一个字符串参数会导致带有消息的 InvalidArgs 错误响应

Type of message, “((sa{sv})sa{ss}u)”, does not match expected type “((sa{sv})sa{ss}us)”

字符串编码了预期的类型

{
{
String,
Dict<String, Variant>
},
String,
Dict<String, String>,
Uint32,
String
}

关于c++ - 如何使用结构参数从 Qt 调用 D-Bus 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74749863/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com