PDA

View Full Version : Namespaces in QtDBus



engelhardt
1st February 2011, 09:57
Hello,

I have a problem concerning the usage of my own types in QtDBus. I managed to make the program work without namespaces, but when I include the type I want to (de)marshall in a namespace, the method using this type does not show up on DBus.

I boiled the whole probem down to the following small (compilable) example:


#ifndef HEADER_HPP
#define HEADER_HPP

#include <QtCore/QCoreApplication>
#include <QtDBus/QtDBus>
#include <QtCore/QObject>
#include <QMetaType>
#include <iostream>

namespace Test {
struct S {
int number;
QString name;
double time;
};
}

QDBusArgument &operator<<(QDBusArgument &argument, const Test::S &arg);
const QDBusArgument &operator>>(const QDBusArgument &argument, Test::S &t);

Q_DECLARE_METATYPE(Test::S)



namespace Test {
class Foo : public QObject {
Q_OBJECT
public:
void foo1() { // some code
}

void foo2(S input) { // some code
}
};


class FooAdaptor : public QDBusAbstractAdaptor {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "com.Test.Foo")
public:
FooAdaptor(Foo* srv_appl) : QDBusAbstractAdaptor(srv_appl) {

setAutoRelaySignals(true);
qDBusRegisterMetaType<S>();
}

public slots:

int foo1() { // some invokation code
}

void foo2(S dummy) { // some invokation code
}
};
}

#endif

// the CPP-File looks like:
#include "header.hpp"

QDBusArgument &operator<<(QDBusArgument &argument, const Test::S &arg) {
argument.beginStructure();

argument << arg.number;
argument << arg.name;
argument << arg.time;

argument.endStructure();
return argument;
}

const QDBusArgument &operator>>(const QDBusArgument &argument, Test::S &arg) {
argument.beginStructure();

argument >> arg.number;
argument >> arg.name;
argument >> arg.time;

argument.endStructure();
return argument;
}

// The main file:
#include <QtCore/QCoreApplication>
#include "header.hpp"
using namespace Test;

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

qDBusRegisterMetaType<S>();

Foo f;
new FooAdaptor(&f);

QDBusConnection connection = QDBusConnection::sessionBus();
connection.registerObject("/com/Test/Foo", &f);
connection.registerService("com.Test.FooService");

return a.exec();
}


But when I run this program and run qdbus, the method foo2 does not show up:


$ qdbus com.Test.FooService /com/Test/Foo
method int com.Test.Foo.foo1()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()


This is irritating to me, as the program works fine, when I leave out the namespace. I also tried to implement the op>> and op<< in the namespace Test (i.e. namespace Test { const QDBusArgument &operator>>(const QDBusArgument &argument, S &arg) ... ). This compiles as well, but the method foo2 does not show up on the DBus. Including Q_DECLARE_METATYPE in the namespace does not compile.

I do not really understand this behavior, as I declare S as a metatype, provide the op<< and op>> and I register the type on DBus. However, the inclusion of the struct in a namespace seems to screw the whole thing up.

What am I doing wrong and how can I fix this?

Thank you very much in advance!

Best regards,
Daniel

MarekR22
2nd February 2011, 08:01
Try first declare and register meta type:

Q_DECLARE_METATYPE(Test::S) // declaration

// this should be before qDBusRegisterMetaType<Test::S>();
qRegisterMetaType<Test::S>();


Another thing what happened to:

Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"com.Test.Foo\">\n"
" <method name=\"foo1\">\n"
" </method>\n"
" <method name=\"foo2\">\n"
" <arg direction=\"in\" type=\"(isd)\" name=\"input\"/>\n"
" </method>\n"
" </interface>\n"
"")

engelhardt
2nd February 2011, 09:29
Hello Marek,

thank you for your reply. I inserted the Q_CLASSINFO macro and it solved the problem. Thank you very much.

I did assume that the Introspection information was not necessary for the workings with DBus, as it does not show up in some official examples from Trolltech, like http://doc.trolltech.com/latest/qdbusadaptorexample.html and so, I planed to leave it out (I do not use the DBus compiler). I guess, I was wrong!

Thank you for clearing this up!