1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
// GDBus++ - glib2 GDBus C++ wrapper
//
// SPDX-License-Identifier: AGPL-3.0-only
//
// Copyright (C) OpenVPN Inc <sales@openvpn.net>
// Copyright (C) David Sommerseth <davids@openvpn.net>
//
/**
* @file example-proxy2.cpp
*
* @brief Variant of example-proxy.cpp which implements the proxy
* as a C++ object
*
* To compile this program:
*
* $ c++ -std=c++17 $(pkg-config gdbuspp glib-2.0 gio-2.0 gio-unix-2.0 --cflags --libs) -o example-proxy2 example-proxy2.cpp
*
*/
#include <iostream>
#include <string>
#include <gdbuspp/connection.hpp>
#include <gdbuspp/proxy.hpp>
#include <gdbuspp/glib2/utils.hpp>
class MyServiceProxy
{
public:
/**
* Enforce this object to always be set up with a smart pointer
*
* @param c
* @return std::shared_ptr<MyServiceProxy>
*/
[[nodiscard]] static std::shared_ptr<MyServiceProxy> Create(DBus::Connection::Ptr c)
{
return std::shared_ptr<MyServiceProxy>(new MyServiceProxy(c));
}
/**
* Calls the net.example.myinterface.MethodWithArgs D-Bus method
* in the /example/myobject D-Bus object in the net.example.myservice
* D-Bus service.
*
* This method takes two string arguments as input and returns a
* a single string in return
*
* @param string1
* @param string2
* @return const std::string
*/
const std::string MethodWithArgs(const std::string &string1,
const std::string &string2)
{
// Create the "argument pack" containing of 2 strings -> (ss)
GVariantBuilder *args_builder = glib2::Builder::Create("(ss)");
glib2::Builder::Add(args_builder, string1);
glib2::Builder::Add(args_builder, string2);
GVariant *arguments = glib2::Builder::Finish(args_builder);
// Perform the D-Bus method call
GVariant *response = proxy->Call(preset,
"MethodWithArgs",
arguments);
// Extract the response from the object. This method returns only a
// single string.
const auto result = glib2::Value::Extract<std::string>(response, 0);
g_variant_unref(response);
return result;
}
/**
* Calls the net.example.myinterface.MyMethod D-Bus method
* in the /example/myobject D-Bus object in the net.example.myservice
* D-Bus service.
*
* This method takes no arguments and provides no response.
*/
void MyMethod()
{
GVariant *response = proxy->Call(preset, "MyMethod");
g_variant_unref(response);
}
/**
* Generic method to retrieve a property value from the service
*
* @tparam T C++ data type to extract the data as; must
* be the equivalent type of the D-Bus object's
* data type
* @param property_name Name of the D-Bus object property
* @return T
*/
template <typename T>
T GetProperty(const std::string &property_name) const
{
return proxy->GetProperty<T>(preset, property_name);
}
/**
* Generic method to modify a property value stored in the service
*
* @tparam T C++ data type to extract the data as; must
* be the equivalent type of the D-Bus object's
* data type
* @param property_name Name of the D-Bus object property
* @param value The new value for the property
*/
template <typename T>
void SetProperty(const std::string &property_name,
const T &value) const
{
proxy->SetProperty(preset, property_name, value);
}
private:
DBus::Proxy::Client::Ptr proxy = nullptr;
DBus::Proxy::TargetPreset::Ptr preset = nullptr;
MyServiceProxy(DBus::Connection::Ptr conn)
{
proxy = DBus::Proxy::Client::Create(conn, "net.example.myservice");
preset = DBus::Proxy::TargetPreset::Create("/example/myobject",
"net.example.myinterface");
}
};
int main(int argc, char **argv)
{
try
{
// Get a connection to the Session D-Bus
auto connection = DBus::Connection::Create(DBus::BusType::SESSION);
// Setup a client proxy to our example-service
auto proxy = MyServiceProxy::Create(connection);
// Call the net.example.myinterface.MyMethod
proxy->MyMethod();
// Call the net.example.myinterface.MethodWithArgs D-Bus method
auto result = proxy->MethodWithArgs("My first string",
"My Second String");
std::cout << "Method call result: " << result << std::endl;
// Retrieve the content of the D-Bus object property, which is a string
auto my_property = proxy->GetProperty<std::string>("my_property");
std::cout << "my_property: " << my_property << std::endl;
// Change this property to a new string
std::string new_property_value = "A changed property";
proxy->SetProperty("my_property", new_property_value);
// Retrieve the same property again to show this value did indeed change
std::cout << "modified property: "
<< proxy->GetProperty<std::string>("my_property")
<< std::endl;
return 0;
}
catch (const DBus::Exception &excp)
{
std::cerr << "EXCEPTION CAUGHT: " << excp.what() << std::endl;
return 2;
}
}
|