微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 DBus 调用给出 UnknownMethod DBus 错误?

如何解决为什么我的 DBus 调用给出 UnknownMethod DBus 错误?

我正在尝试使用 DBus 调用管理 systemd 服务。但是,我似乎无法找出进行方法调用的正确方法,因为无论我做什么都会引发 DBus 错误

// Create connection
auto connection = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::BUS_TYPE_SESSION);
// Create the parameters vector
std::vector<std::string> param_vec;
param_vec.push_back("my_unit_name");
auto param_vec_variant = Glib::Variant<std::vector<std::string>>::create(param_vec);
auto params = Glib::Variant<std::vector<std::string>>::create_tuple(param_vec_variant);

try {
    // Make the "GetUnit" dbus call to systemd
    auto response = connection->call_sync(
        "/org/freedesktop/systemd1","org.freedesktop.systemd1.Manager","GetUnit",params
    );
}
catch (Gio::DBus::Error err) {
    // org.freedesktop.DBus.Error.UnkNownMethod being thrown
    std::cerr << Gio::DBus::ErrorUtils::get_remote_error(err) << std::endl;
}

谁能指出我哪里出错了?

解决方法

正如 Philip 指出的那样,我的问题出在 connection->call_sync 方法上,该方法采用默认参数 bus_name = "" (docs)。

systemd 的 bus_nameorg.freedesktop.systemd1,因此解决此问题的正确方法是添加此参数:

auto response = connection->call_sync(
    "/org/freedesktop/systemd1","org.freedesktop.systemd1.Manager","GetUnit",params,"org.freedesktop.systemd1" // bus_name
);

但是,在进一步挖掘之后,我发现实际上是 not recommended 使用 Connection 对象进行 DBus 调用,而且我实际上应该使用 Proxy

最终我使用可变参数概括了我的代码并确定了这个函数(为了可读性而删除了 try-catch 块):

template <typename... Types>
Glib::VariantContainerBase dbus_call(const Glib::ustring& method,const Types&... params) {
    auto proxy = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BusType::BUS_TYPE_SESSION,"org.freedesktop.systemd1","/org/freedesktop/systemd1","org.freedesktop.systemd1.Manager");
    auto params_variant = Glib::Variant<std::tuple<Types...>>::create(std::tuple<Types...>(params...));

    return proxy->call_sync(method,params_variant);
}

可以这样调用:

auto response = dbus_call("GetUnit","my_unit_name");

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。