Difference between revisions of "TDE DBus Tutorial"
imported>Deloptes |
imported>Deloptes (updated to match the status of dbus-1-tqt) |
||
Line 1: | Line 1: | ||
=Introduction= |
=Introduction= |
||
− | + | This is a brief introduction on auto-generated DBus interfaces and proxies and their use in TDE. |
|
− | I hope it will save many time |
+ | I hope it will save many people time and headache. |
+ | Some more information can be found in the documentation of package dbus-1-tqt. |
||
+ | The examples were moved to [https://mirror.git.trinitydesktop.org/gitea/deloptes/dbus-1-tqt-example dbus-1-tqt-example] |
||
− | Here are two examples to show the use of DBus proxy and DBus interface. |
||
+ | All the examples are based on the example in dbus-1-tqt for a service providing method “ListSorter” and for such a client. |
||
− | Additional information can be found in the documentation of package dbus-1-tqt, but I spent almost 2 days until magic combination of following steps came out. |
||
=Create DBus Interface= |
=Create DBus Interface= |
||
Line 29: | Line 30: | ||
=Generate the code= |
=Generate the code= |
||
− | To generate the TQt C++ classes use dbusxml2qt3 |
+ | To generate the TQt C++ classes we use dbusxml2qt3 |
$ dbusxml2qt3 sortexample.xml |
$ dbusxml2qt3 sortexample.xml |
||
Line 37: | Line 38: | ||
in the second step generate the proxy with unique namespace to fit your application |
in the second step generate the proxy with unique namespace to fit your application |
||
− | $/usr/bin/dbusxml2qt3 sortexample.xml |
+ | $/usr/bin/dbusxml2qt3 sortexample.xml |
the result is |
the result is |
||
− | $ ls -1 |
+ | $ ls -1 |
− | + | dbusbaseNode.cpp |
|
− | + | dbusbaseNode.h |
|
− | + | introspectableInterface.cpp |
|
− | + | introspectableInterface.h |
|
− | + | serviceInterface.cpp |
|
− | + | serviceInterface.h |
|
− | + | serviceNode.cpp |
|
− | + | serviceNode.h |
|
+ | serviceProxy.cpp |
||
+ | serviceProxy.h |
||
sortexample.xml |
sortexample.xml |
||
+ | =Implement the Service= |
||
− | We have to correct few errors introduced by the generator |
||
+ | Now we can create our own service using the interface use the proxy as shown below. |
||
− | * <*>node.cpp file missing "interface" in the include |
||
+ | ==testservice.h== |
||
− | // interface classes includes |
||
− | #include "service''interface''.h" |
||
+ | #include <tqdbusconnection.h> |
||
− | * <*>proxy.cpp you need to add whatever your proxy is called .moc at the end |
||
+ | #include <tqdbusobject.h> |
||
+ | #include <tqmap.h> |
||
+ | #include "serviceInterface.h" |
||
+ | #include "serviceNode.h" |
||
+ | class Interface1 : public org::example::ServiceInterface |
||
− | ''#include "serviceproxy.moc"'' |
||
− | + | { |
|
+ | public: |
||
− | |||
+ | Interface1(TQT_DBusConnection&); |
||
− | =Implement the Service= |
||
+ | virtual ~Interface1(); |
||
− | |||
+ | protected: // implement methods |
||
− | Now we can create our own service using the interface from step one, or create our own proxy from step two |
||
+ | virtual bool ListSorter(const TQStringList& input, TQStringList& output, TQT_DBusError& error); |
||
− | |||
+ | protected: // implement sending replies |
||
− | ==testservice.h== |
||
+ | virtual void handleMethodReply(const TQT_DBusMessage& reply); |
||
+ | private: |
||
+ | TQT_DBusConnection *m_connection; |
||
+ | }; |
||
+ | class MultiInterfaceService : public org::example::ServiceNode |
||
− | #include <tqdbusconnection.h> |
||
+ | { |
||
− | #include <tqdbusobject.h> |
||
+ | public: |
||
− | #include <tqmap.h> |
||
+ | MultiInterfaceService(TQT_DBusConnection&); |
||
− | #include "serviceinterface.h" |
||
− | #include "org_example_servicenode.h" |
||
− | |||
− | class Interface1 : public org::example::Service |
||
− | { |
||
− | public: |
||
− | Interface1(TQT_DBusConnection&); |
||
− | virtual ~Interface1(); |
||
− | protected: // implement methods |
||
− | virtual bool ListSorter(const TQStringList& input, TQStringList& output, TQT_DBusError& error); |
||
− | protected: // implement sending replies |
||
− | virtual void handleMethodReply(const TQT_DBusMessage& reply); |
||
− | private: |
||
− | TQT_DBusConnection *m_connection; |
||
− | }; |
||
− | |||
− | class MultiInterfaceService : public org_example_Service |
||
− | { |
||
− | public: |
||
− | MultiInterfaceService(TQT_DBusConnection&); |
||
~MultiInterfaceService(); |
~MultiInterfaceService(); |
||
− | + | protected: |
|
virtual TQT_DBusObjectBase* createInterface(const TQString&); |
virtual TQT_DBusObjectBase* createInterface(const TQString&); |
||
− | + | private: |
|
− | + | TQMap<TQString, TQT_DBusObjectBase*> m_interfaces; |
|
− | + | TQT_DBusConnection m_connection; |
|
− | + | }; |
|
==testservice.cpp== |
==testservice.cpp== |
||
− | + | #include <kdebug.h> |
|
+ | |||
− | #include <kdebug.h> |
||
− | + | // TQt includes |
|
+ | #include <tqdom.h> |
||
− | // TQt includes |
||
− | + | #include <tqstring.h> |
|
− | + | #include <tqstringlist.h> |
|
− | + | #include <tqdbuserror.h> |
|
− | + | #include <tqdbusmessage.h> |
|
− | + | #include <tqdbusdatalist.h> |
|
+ | |||
− | #include <tqdbusdatalist.h> |
||
+ | #include "testservice.h" |
||
− | |||
+ | |||
− | Interface1::Interface1(TQT_DBusConnection &conn) |
||
+ | Interface1::Interface1(TQT_DBusConnection &conn) |
||
: m_connection(&conn) |
: m_connection(&conn) |
||
− | + | { |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
− | + | } |
|
− | + | Interface1::~Interface1(){ |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
− | + | } |
|
+ | |||
− | |||
− | + | void Interface1::handleMethodReply(const TQT_DBusMessage& reply) { |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
// do something |
// do something |
||
m_connection->send(reply); |
m_connection->send(reply); |
||
− | + | } |
|
+ | |||
− | |||
− | + | bool Interface1::ListSorter(const TQStringList& input, TQStringList& output, TQT_DBusError& error) { |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
output = input; |
output = input; |
||
output.sort(); |
output.sort(); |
||
return true; |
return true; |
||
− | + | } |
|
+ | |||
− | |||
− | + | MultiInterfaceService::MultiInterfaceService(TQT_DBusConnection &connection ) |
|
− | : |
+ | : org::example::ServiceNode(), m_connection(connection) |
− | + | { |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
m_interfaces.insert("org.freedesktop.DBus.Introspectable", this); |
m_interfaces.insert("org.freedesktop.DBus.Introspectable", this); |
||
m_interfaces.insert("org.example.Service", new Interface1(m_connection)); |
m_interfaces.insert("org.example.Service", new Interface1(m_connection)); |
||
registerObject(m_connection,"/"); |
registerObject(m_connection,"/"); |
||
− | + | } |
|
+ | |||
− | |||
− | + | MultiInterfaceService::~MultiInterfaceService(){ |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
− | + | } |
|
+ | |||
− | |||
− | + | TQT_DBusObjectBase* MultiInterfaceService::createInterface(const TQString& interfaceName) |
|
− | + | { |
|
kdDebug() << k_funcinfo << endl; |
kdDebug() << k_funcinfo << endl; |
||
kdDebug() << "Interface Name: " << interfaceName << endl; |
kdDebug() << "Interface Name: " << interfaceName << endl; |
||
− | + | return (TQT_DBusObjectBase*) m_interfaces[interfaceName]; |
|
− | + | } |
|
==tqdbusexample.cpp== |
==tqdbusexample.cpp== |
||
− | + | #include "testservice.h" |
|
− | + | #include <tqapplication.h> |
|
− | + | #include <tqdbusconnection.h> |
|
+ | |||
− | |||
− | + | int main(int argc, char** argv) |
|
− | + | { |
|
TQApplication app(argc, argv, false); |
TQApplication app(argc, argv, false); |
||
TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); |
TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); |
||
− | + | // TQT_DBusConnection connection = TQT_DBusConnection::systemBus(); |
|
if (!connection.isConnected()) |
if (!connection.isConnected()) |
||
tqFatal("Cannot connect to session bus"); |
tqFatal("Cannot connect to session bus"); |
||
Line 181: | Line 173: | ||
} |
} |
||
MultiInterfaceService service(connection); |
MultiInterfaceService service(connection); |
||
+ | |||
− | |||
return app.exec(); |
return app.exec(); |
||
− | + | } |
|
==buildtqdbusexample.sh== |
==buildtqdbusexample.sh== |
||
− | + | /usr/bin/g++ -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time \ |
|
− | + | -D_FORTIFY_SOURCE=2 -DQT_NO_ASCII_CAST -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT \ |
|
− | + | -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT -D_REENTRANT -include tqt.h -I/usr/include/tqt3 \ |
|
− | + | -I/opt/trinity/include/ -I/usr/include/dbus-1-tqt -I/usr/include/tqt -I -DQT_NO_ASCII_CAST \ |
|
− | + | -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT \ |
|
− | + | -D_REENTRANT -include tqt.h -g -Wl,-z,relro tqdbusexample.cpp testservice.cpp \ |
|
− | + | serviceNode.cpp introspectableInterface.cpp serviceInterface.cpp \ |
|
− | + | -o tqdbusexample -ldbus-1-tqt \ |
|
− | + | /opt/trinity/lib/libtdeparts.so.2.1.0 /opt/trinity/lib/libtdeio.so.14.0.0 \ |
|
− | + | /opt/trinity/lib/libtdecore.so.14.0.0 -ltqt -ltqt-mt -lXrender -lX11 -lc \ |
|
− | + | /usr/lib/x86_64-linux-gnu/libz.so -lidn -lXcomposite -lICE -lSM -lutil -lr -lacl -lattr -ltqui |
|
− | |||
Line 207: | Line 198: | ||
==tqdbusproxy.cpp== |
==tqdbusproxy.cpp== |
||
− | + | #include <tqstringlist.h> |
|
− | + | #include <tqdbusconnection.h> |
|
− | + | #include "serviceProxy.h" |
|
+ | |||
− | |||
− | + | int main(int argc, char** argv) |
|
− | + | { |
|
+ | |||
− | |||
TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); |
TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); |
||
− | + | // TQT_DBusConnection connection = TQT_DBusConnection::systemBus(); |
|
if (!connection.isConnected()) |
if (!connection.isConnected()) |
||
tqFatal("Cannot connect to session bus"); |
tqFatal("Cannot connect to session bus"); |
||
+ | |||
− | |||
− | + | org::example::ServiceProxy serviceProxy("org.example.Service", "/"); |
|
+ | |||
− | |||
serviceProxy.setConnection(connection); |
serviceProxy.setConnection(connection); |
||
+ | |||
− | |||
TQStringList list; |
TQStringList list; |
||
list << "D" << "C" << "B" << "A"; |
list << "D" << "C" << "B" << "A"; |
||
+ | |||
− | |||
tqWarning("OUTPUT BEFORE SORT"); |
tqWarning("OUTPUT BEFORE SORT"); |
||
for (TQStringList::iterator it= list.begin(); it != list.end(); ++it) { |
for (TQStringList::iterator it= list.begin(); it != list.end(); ++it) { |
||
tqWarning("\t%s",(*it).utf8().data()); |
tqWarning("\t%s",(*it).utf8().data()); |
||
} |
} |
||
+ | |||
− | |||
TQStringList data; |
TQStringList data; |
||
TQT_DBusError error; |
TQT_DBusError error; |
||
Line 242: | Line 233: | ||
} |
} |
||
} |
} |
||
+ | |||
− | |||
return 0; |
return 0; |
||
− | + | } |
|
==buildtqdbusproxy.sh== |
==buildtqdbusproxy.sh== |
||
+ | tmoc serviceProxy.h -o serviceProxy.moc |
||
− | /usr/bin/g++ -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time \ |
||
+ | /usr/bin/g++ -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time \ |
||
− | -D_FORTIFY_SOURCE=2 -DQT_NO_ASCII_CAST -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT \ |
||
+ | -D_FORTIFY_SOURCE=2 -DQT_NO_ASCII_CAST -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT \ |
||
− | -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT -D_REENTRANT -include tqt.h -I/usr/include/tqt3 \ |
||
− | - |
+ | -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT -D_REENTRANT -include tqt.h -I/usr/include/tqt3 \ |
+ | -I/opt/trinity/include/ -I/usr/include/dbus-1-tqt -I/usr/include/tqt -I -DQT_NO_ASCII_CAST \ |
||
− | -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT \ |
||
+ | -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT \ |
||
− | -D_REENTRANT -include tqt.h -g -Wl,-z,relro tqdbusproxy.cpp serviceproxy.cpp \ |
||
+ | -D_REENTRANT -include tqt.h -g -Wl,-z,relro tqdbusproxy.cpp serviceProxy.cpp \ |
||
− | -o tqdbusproxy -ldbus-1-tqt \ |
||
+ | -o tqdbusproxy -ldbus-1-tqt \ |
||
− | /opt/trinity/lib/libtdeparts.so.2.1.0 /opt/trinity/lib/libtdeio.so.14.0.0 \ |
||
− | + | /opt/trinity/lib/libtdeparts.so.2.1.0 /opt/trinity/lib/libtdeio.so.14.0.0 \ |
|
− | + | /opt/trinity/lib/libtdecore.so.14.0.0 -ltqt -ltqt-mt -lXrender -lX11 -lc \ |
|
+ | /usr/lib/x86_64-linux-gnu/libz.so -lidn -lXcomposite -lICE -lSM -lutil -lr -lacl -lattr -ltqui |
||
+ | |||
=Try it= |
=Try it= |
||
Line 268: | Line 261: | ||
$ dbus-send --print-reply --session --dest=org.example.Service / org.example.Service.ListSorter array:string:"B","A","C" |
$ dbus-send --print-reply --session --dest=org.example.Service / org.example.Service.ListSorter array:string:"B","A","C" |
||
− | method return time= |
+ | method return time=1571779738.342213 sender=:1.91 -> destination=:1.94 serial=7 reply_serial=2 |
array [ |
array [ |
||
string "A" |
string "A" |
||
Line 274: | Line 267: | ||
string "C" |
string "C" |
||
] |
] |
||
+ | |||
==Test the service with proxy client== |
==Test the service with proxy client== |
||
− | ./tqdbusproxy |
+ | $ ./tqdbusproxy |
+ | [2019/10/22 23:28:11.982] OUTPUT BEFORE SORT |
||
+ | [2019/10/22 23:28:11.983] D |
||
+ | [2019/10/22 23:28:11.983] C |
||
+ | [2019/10/22 23:28:11.983] B |
||
+ | [2019/10/22 23:28:11.983] A |
||
+ | [2019/10/22 23:28:11.983] OUTPUT AFTER SORT |
||
+ | [2019/10/22 23:28:11.983] A |
||
+ | [2019/10/22 23:28:11.983] B |
||
+ | [2019/10/22 23:28:11.983] C |
||
+ | [2019/10/22 23:28:11.983] D |
||
− | OUTPUT BEFORE SORT |
||
− | D |
||
− | C |
||
− | B |
||
− | A |
||
− | OUTPUT AFTER SORT |
||
− | A |
||
− | B |
||
− | C |
||
− | D |
||
=Sample code= |
=Sample code= |
Revision as of 21:36, 22 October 2019
Introduction
This is a brief introduction on auto-generated DBus interfaces and proxies and their use in TDE.
I hope it will save many people time and headache. Some more information can be found in the documentation of package dbus-1-tqt.
The examples were moved to dbus-1-tqt-example
All the examples are based on the example in dbus-1-tqt for a service providing method “ListSorter” and for such a client.
Create DBus Interface
To create a DBus interface we need first a definition of the interface. More information on the interface type and signatures can be found in official dbus tutorial
The definition of the interface is a xml file. We take as example a file describing "org.example.Service" that has one method "ListSorter". The generated code will automatically include the Introspection interface and we will see how we can create a service to handle both interfaces.
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node name="/org/example/Service"> <interface name="org.example.Service"> <method name="ListSorter"> <arg name="input" type="as" direction="in" /> <arg name="output" type="as" direction="out" /> </method> </interface> </node>
Generate the code
To generate the TQt C++ classes we use dbusxml2qt3
$ dbusxml2qt3 sortexample.xml ClassGenerator: processing interface 'org.example.Service' Generating org.freedesktop.DBus.Introspectable on demand
in the second step generate the proxy with unique namespace to fit your application
$/usr/bin/dbusxml2qt3 sortexample.xml
the result is
$ ls -1 dbusbaseNode.cpp dbusbaseNode.h introspectableInterface.cpp introspectableInterface.h serviceInterface.cpp serviceInterface.h serviceNode.cpp serviceNode.h serviceProxy.cpp serviceProxy.h sortexample.xml
Implement the Service
Now we can create our own service using the interface use the proxy as shown below.
testservice.h
#include <tqdbusconnection.h> #include <tqdbusobject.h> #include <tqmap.h> #include "serviceInterface.h" #include "serviceNode.h"
class Interface1 : public org::example::ServiceInterface { public: Interface1(TQT_DBusConnection&); virtual ~Interface1(); protected: // implement methods virtual bool ListSorter(const TQStringList& input, TQStringList& output, TQT_DBusError& error); protected: // implement sending replies virtual void handleMethodReply(const TQT_DBusMessage& reply); private: TQT_DBusConnection *m_connection; };
class MultiInterfaceService : public org::example::ServiceNode { public: MultiInterfaceService(TQT_DBusConnection&); ~MultiInterfaceService(); protected: virtual TQT_DBusObjectBase* createInterface(const TQString&); private: TQMap<TQString, TQT_DBusObjectBase*> m_interfaces; TQT_DBusConnection m_connection; };
testservice.cpp
#include <kdebug.h>
// TQt includes #include <tqdom.h> #include <tqstring.h> #include <tqstringlist.h> #include <tqdbuserror.h> #include <tqdbusmessage.h> #include <tqdbusdatalist.h>
#include "testservice.h"
Interface1::Interface1(TQT_DBusConnection &conn) : m_connection(&conn) { kdDebug() << k_funcinfo << endl; } Interface1::~Interface1(){ kdDebug() << k_funcinfo << endl; }
void Interface1::handleMethodReply(const TQT_DBusMessage& reply) { kdDebug() << k_funcinfo << endl; // do something m_connection->send(reply); }
bool Interface1::ListSorter(const TQStringList& input, TQStringList& output, TQT_DBusError& error) { kdDebug() << k_funcinfo << endl; output = input; output.sort(); return true; }
MultiInterfaceService::MultiInterfaceService(TQT_DBusConnection &connection ) : org::example::ServiceNode(), m_connection(connection) { kdDebug() << k_funcinfo << endl; m_interfaces.insert("org.freedesktop.DBus.Introspectable", this); m_interfaces.insert("org.example.Service", new Interface1(m_connection)); registerObject(m_connection,"/"); }
MultiInterfaceService::~MultiInterfaceService(){ kdDebug() << k_funcinfo << endl; }
TQT_DBusObjectBase* MultiInterfaceService::createInterface(const TQString& interfaceName) { kdDebug() << k_funcinfo << endl; kdDebug() << "Interface Name: " << interfaceName << endl; return (TQT_DBusObjectBase*) m_interfaces[interfaceName]; }
tqdbusexample.cpp
#include "testservice.h" #include <tqapplication.h> #include <tqdbusconnection.h>
int main(int argc, char** argv) { TQApplication app(argc, argv, false); TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); // TQT_DBusConnection connection = TQT_DBusConnection::systemBus(); if (!connection.isConnected()) tqFatal("Cannot connect to session bus"); // try to get a specific service name if (!connection.requestName("org.example.Service")) { tqWarning("Requesting name 'org.example.Service' failed. " "Will only be addressable through unique name '%s'", connection.uniqueName().local8Bit().data()); } else { tqDebug("Requesting name 'org.example.Service' successfull"); } MultiInterfaceService service(connection);
return app.exec(); }
buildtqdbusexample.sh
/usr/bin/g++ -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time \ -D_FORTIFY_SOURCE=2 -DQT_NO_ASCII_CAST -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT \ -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT -D_REENTRANT -include tqt.h -I/usr/include/tqt3 \ -I/opt/trinity/include/ -I/usr/include/dbus-1-tqt -I/usr/include/tqt -I -DQT_NO_ASCII_CAST \ -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT \ -D_REENTRANT -include tqt.h -g -Wl,-z,relro tqdbusexample.cpp testservice.cpp \ serviceNode.cpp introspectableInterface.cpp serviceInterface.cpp \ -o tqdbusexample -ldbus-1-tqt \ /opt/trinity/lib/libtdeparts.so.2.1.0 /opt/trinity/lib/libtdeio.so.14.0.0 \ /opt/trinity/lib/libtdecore.so.14.0.0 -ltqt -ltqt-mt -lXrender -lX11 -lc \ /usr/lib/x86_64-linux-gnu/libz.so -lidn -lXcomposite -lICE -lSM -lutil -lr -lacl -lattr -ltqui
Using a Proxy
We will use the service from our first example and implement a proxy to utilize the service.
tqdbusproxy.cpp
#include <tqstringlist.h> #include <tqdbusconnection.h> #include "serviceProxy.h"
int main(int argc, char** argv) {
TQT_DBusConnection connection = TQT_DBusConnection::sessionBus(); // TQT_DBusConnection connection = TQT_DBusConnection::systemBus(); if (!connection.isConnected()) tqFatal("Cannot connect to session bus");
org::example::ServiceProxy serviceProxy("org.example.Service", "/");
serviceProxy.setConnection(connection);
TQStringList list; list << "D" << "C" << "B" << "A";
tqWarning("OUTPUT BEFORE SORT"); for (TQStringList::iterator it= list.begin(); it != list.end(); ++it) { tqWarning("\t%s",(*it).utf8().data()); }
TQStringList data; TQT_DBusError error; if (!serviceProxy.ListSorter(list,data,error)) { tqFatal("'org.example.Service.ListSorter' failed. "); } else { tqWarning("OUTPUT AFTER SORT"); for (TQStringList::iterator it = data.begin(); it != data.end(); ++it) { tqWarning("\t%s",(*it).utf8().data()); } }
return 0; }
buildtqdbusproxy.sh
tmoc serviceProxy.h -o serviceProxy.moc /usr/bin/g++ -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time \ -D_FORTIFY_SOURCE=2 -DQT_NO_ASCII_CAST -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT \ -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT -D_REENTRANT -include tqt.h -I/usr/include/tqt3 \ -I/opt/trinity/include/ -I/usr/include/dbus-1-tqt -I/usr/include/tqt -I -DQT_NO_ASCII_CAST \ -DQT_CLEAN_NAMESPACE -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION -DQT_THREAD_SUPPORT \ -D_REENTRANT -include tqt.h -g -Wl,-z,relro tqdbusproxy.cpp serviceProxy.cpp \ -o tqdbusproxy -ldbus-1-tqt \ /opt/trinity/lib/libtdeparts.so.2.1.0 /opt/trinity/lib/libtdeio.so.14.0.0 \ /opt/trinity/lib/libtdecore.so.14.0.0 -ltqt -ltqt-mt -lXrender -lX11 -lc \ /usr/lib/x86_64-linux-gnu/libz.so -lidn -lXcomposite -lICE -lSM -lutil -lr -lacl -lattr -ltqui
Try it
Start the service
./tqdbusexample
Test the service from command line
$ dbus-send --print-reply --session --dest=org.example.Service / org.example.Service.ListSorter array:string:"B","A","C" method return time=1571779738.342213 sender=:1.91 -> destination=:1.94 serial=7 reply_serial=2 array [ string "A" string "B" string "C" ]
Test the service with proxy client
$ ./tqdbusproxy [2019/10/22 23:28:11.982] OUTPUT BEFORE SORT [2019/10/22 23:28:11.983] D [2019/10/22 23:28:11.983] C [2019/10/22 23:28:11.983] B [2019/10/22 23:28:11.983] A [2019/10/22 23:28:11.983] OUTPUT AFTER SORT [2019/10/22 23:28:11.983] A [2019/10/22 23:28:11.983] B [2019/10/22 23:28:11.983] C [2019/10/22 23:28:11.983] D