我正在尝试使用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;
}有谁能指出我哪里错了吗?
发布于 2021-06-30 17:09:11
正如Philip所指出的,我的问题出在connection->call_sync方法上,它接受默认参数bus_name = "" (docs)。
systemd的bus_name是org.freedesktop.systemd1,所以这个问题的正确解决方案应该是添加这个参数:
auto response = connection->call_sync(
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"GetUnit",
params,
"org.freedesktop.systemd1" // bus_name
);然而,在进一步研究之后,我发现对DBus调用使用Connection对象实际上是not recommended,而我实际上应该使用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");https://stackoverflow.com/questions/68181458
复制相似问题