PDA

View Full Version : QDBus : Send an array of objects (C++)



lordjoseph
24th January 2012, 18:19
Hello,

I have to send on the dbus an array of objects but I don't know how to do it.
I have a class that contains four variables and I need to create an array of objects of this class and to send it to another application on dbus.
I read the tutorial about the custom type but I didn't understand well how to modify operator << and >> , and how to modify the xml file in order to produce the interface and the adaptor.
In the xml file I used type="(iiii)" and I added the annotation row but in this one I don't know what I have to write if the value is an array of objects...
Does anyone can help me please?

Thanks you in advance

lordjoseph
25th January 2012, 13:30
In the xml file what type do I have to write in the arg if the arg is a QList<MyClass> ?

MarekR22
25th January 2012, 15:16
http://dbus.freedesktop.org/doc/dbus-specification.html#type-system
in your case it will be:

a(iiii)

Added after 14 minutes:

for operators it is quite simple (http://developer.qt.nokia.com/doc/qt-4.8/qdbusargument.html#details).
You don't have to do it for QList (template will handle that).
Remember (http://developer.qt.nokia.com/doc/qt-4.8/qdbustypesystem.html#extending-the-type-system) to declare meta type for struct and register dbus type

lordjoseph
25th January 2012, 16:08
I'm already using it but I have some problem....



<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.my.test">
<signal name="signalSent">
<arg name="asignals" type="a(iiii)" direction="out"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="SignalsArray"/>
</signal>
<method name="SetSignal">
<arg name="asignals" type="a(iiii)" direction="out"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="SignalsArray"/>
</method>
</interface>
</node>

/****************************** TxSignal.h *************/
#include <QtDBus>
#include <QtCore/QList>
#include <QtCore/QMetaType>


class TxSignal {


public:
TxSignal();
virtual ~TxSignal();


//Getter
QString getSurname();
QString getName();
float getValue();

//Setter
void setSurname(QString Surname);
void setName(QString Name);
void setValue(float Value);


//register Message with the Qt type system
//static void registerMetaType();
friend const QDBusArgument &operator>>(const QDBusArgument &argument, TxSignal &msignals);
friend QDBusArgument &operator<<(QDBusArgument &argument, const TxSignal &msignals);



public:
QString m_Surname;
QString m_Name;
double m_Value;

};

typedef QList<TxSignal> SignalsArray;

Q_DECLARE_METATYPE(TxSignal);
Q_DECLARE_METATYPE(SignalsArray);

inline void registerCommType(){
qDBusRegisterMetaType<TxSignal>();
qDBusRegisterMetaType< SignalsArray >();
}

/****************************************** TxSignal.cpp *************************************************/


#include "TxSignal.h"

TxSignal::TxSignal() {
// TODO Auto-generated constructor stub

}

TxSignal::~TxSignal() {
// TODO Auto-generated destructor stub
}

QDBusArgument &operator <<(QDBusArgument &argument, const TxSignal &msignals)
{
argument.beginStructure();
argument << msignals.m_Surname;
argument << msignals.m_Name;
argument << msignals.m_Value;
argument.endStructure();

return argument;
}

const QDBusArgument &operator >>(const QDBusArgument &argument, TxSignal &msignals)
{
argument.beginStructure();
argument >> msignals.m_Surname;
argument >> msignals.m_Name;
argument >> msignals.m_Value;
argument.endStructure();
return argument;
}

QString TxSignal::getName()
{
return this->m_Name ;
}

QString TxSignal::getSurname()
{
return this->m_Surname ;
}

float TxSignal::getValue()
{
return this->m_Value ;
}

void TxSignal::setName(QString Name)
{
this->m_Name = Name;

}

void TxSignal::setSurname(QString Surname)
{
this->m_Surname = Surname;
}


void TxSignal::setValue(float Value)
{
this->m_Value = Value;
}
/*************************************** TestSignal.h *********************************************/

#include <QObject>
#include <QStringList>
#include "TxSignal.h"


class TestSignal : public QObject{

Q_OBJECT

//Local variables
QString m_Surname;
QList<TxSignal> m_asignals;

Q_CLASSINFO("D-Bus Interface", "org.my.test")

public:
TestSignal(QObject* parent = 0);
virtual ~TestSignal();

signals:

void signalSent(const SignalsArray &asignals);

public slots:

void SetSignal(const SignalsArray &asignals);


};

/*************************************** TestSignal.cpp *******************************************/

#include <iostream>
using namespace std;
#include "TestSignal.h"
#include "TestSignalAdaptor.h"
#include "TestSignalInterface.h"

TestSignal::TestSignal(QObject *parent) {
// add our D-Bus interface and connect to D-Bus
new TestsignalAdaptor(this);
QDBusConnection::sessionBus().registerService("org.my.test");
QDBusConnection::sessionBus().registerObject("/org/my/test", this);

org::my::test *iface;
iface = new org::my::test(QString(), QString(), QDBusConnection::sessionBus(), this);
bool ret;
ret = connect(iface, SIGNAL(signalSent(SignalsArray)),this, SLOT(SetSignal(SignalsArray)));
if (ret==TRUE) {
cout<<"\nTRUEEEEE";
fflush(stdout);
}
SignalsArray prova;
TxSignal nuovo;
nuovo.m_Surname = "111222333";
nuovo.m_Name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA****";
prova.append(nuovo);

int i=0;
for(i=0;i<20;i++);
emit signalSent(prova);

cout<<"\nSent";

}


void TestSignal::TestSignal(const SignalsArray &asignals)
{
cout<<asignals.at(0).m_Surname.toAscii().data();
cout<<"\nMetodo richiamato";
fflush(stdout);

}

TestSignal::~TestSignal() {
// TODO Auto-generated destructor stub
}



In this way I can't read the QList sent, if I try to send a QString it works fine(after modifying the xml and the code) , so where is the problem?
Can you help me?

Thanks

MarekR22
25th January 2012, 20:53
problem is that type in xml is wrong.
i - means 32 bit integer value and you don't have ANY int values in you structure.
your type description in xml should be: "a(ssd)"
a - stands for array
s - stands for string
d - stands for double

also contents of xml should be in class declaration as a meta data in Q_CLASSINFO().

See qt documentation and examples of d-bus. Apparently you didn't read that carefully.

lordjoseph
25th January 2012, 22:21
I read that (iiii) can be used for every type... am I wrong?
xml should be in the class?
it is in the Adaptor file generated by qdbusxml2cpp tool, anywhere else right?

MarekR22
26th January 2012, 12:22
You had to misunderstand something.
Check table how to describe d-bus types (http://dbus.freedesktop.org/doc/dbus-specification.html#type-system).
See some example (http://developer.qt.nokia.com/doc/qt-4.8/dbus-dbus-chat-chat-adaptor-h.html).