sdbusplus:定义及访问map类型的method
dbus允许定义使用map作为参数的method(但是不能使用struct作为参数)。
可以定义一个如下的service:
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus.hpp>
#include <nlohmann/json.hpp>
#include <iostream>
#include <string>
#include <map>
#include <variant>using namespace std;
using json = nlohmann::json;using variantT = variant<int, string>;
auto doMap(map<string, variantT>& options)
{for(auto& i : options){cout<<i.first<<" ";if(i.second.index() == 0){cout<<get<int>(i.second)<<endl;}else{cout<<get<string>(i.second)<<endl;}}return options;
}int main()
{boost::asio::io_context io;auto conn = std::make_shared<sdbusplus::asio::connection>(io);conn->request_name("demo.service");auto server = sdbusplus::asio::object_server(conn);shared_ptr<sdbusplus::asio::dbus_interface> iface = server.add_interface("/demo_obj","demo_infterface.data");iface->register_method("Map", doMap);iface->initialize();io.run();return 0;
}
运行程序后,可以查看到如下类型的接口:
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
demo_infterface.data interface - - -
.Map method a{sv} a{sv} -
org.freedesktop.DBus.Introspectable interface - - -
.Introspect method - s -
org.freedesktop.DBus.Peer interface - - -
.GetMachineId method - s -
.Ping method - - -
org.freedesktop.DBus.Properties interface - - -
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
其中Map方法的参数类型和返回值类型均为a{sv} ,代表这是一个map。
定义一个client来访问该service:
#include <iostream>
#include <boost/asio.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <string>
#include <map>
#include <variant>using namespace std;
using namespace sdbusplus;using variantT = variant<int, string>;void syncCallMethod()
{boost::asio::io_context io;auto b = bus::new_default_user();auto conn = make_shared<sdbusplus::asio::connection>(io, bus::details::bus_friend::get_busp(b));auto methodCall = conn->new_method_call("demo.service", "/demo_obj","demo_infterface.data", "Map");map<string, variantT> options = {{"name", variantT("xiaoming")}, {"age", variantT(15)}};methodCall.append(options);auto reply = conn->call(methodCall);map<string, variantT> res;reply.read(res);for(auto& i : res){cout<<i.first<<" ";if(i.second.index() == 0){cout<<get<int>(i.second)<<endl;}else{cout<<get<string>(i.second)<<endl;}}
}int main()
{syncCallMethod();return 0;
}
编译程序:
g++ -o sync ./sync_method.cpp -lsdbusplus -lsystemd -std=c++20
运行程序
client端输出:
age 15
name xiaoming