Question

I'm using qt dbus binding in c++.

Currently I'm able to send any custom types (e.g.: class, structs) over dbus but I am not able to send an enumeration.

I also tried this link here, but I do not get it

Was it helpful?

Solution

I found a solution for my problem:

First create a new header file called enums.h which looks like:

#ifndef ENUMS_H
#define ENUMS_H

#include <QtDBus>
#include "enumDBus.h"

enum Color {
    RED = 0,
    BLUE,
    GREEN
};

Q_DECLARE_METATYPE(Color)

#endif  /* ENUMS_H */

Note following line #include "enumDBus.h", you can find this header file here.

So after you declared the enum you can declare a method which takes the enum as argument, in this example I declared following method in calculator.h:

void setColor(Color color);

The implementation for this method:

void Calculator::setColor(Color c)
{
    switch (c) {
    case BLUE: std::cout << "Color: blue" << std::endl;
        break;
    case GREEN: std::cout << "Color: green" << std::endl;
        break;
    case RED: std::cout << "Color: reed" << std::endl;
        break;
    default:
        std::cout << "Color: FAIL!" << std::endl;
    }
}

Now let's generate the Interface description (XML), use following command

qdbuscpp2xml -M -s calculator.h -o com.meJ.system.CalculatorInterface.xml

The generation of method which contains custom types doesn't work properly, so we need to do some adjustments:

<!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="com.meJ.system.CalculatorInterface">
    <method name="setColor">
        <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="Color"/>
        <arg type="(i)" direction="in" name="c"/>
    </method>
  </interface>
</node>

With this XML file we can simply create our adaptors and interfaces classes.

In our main.cpp (on client and server!) we have to register our custom type:

int main(int argc, char** argv)
{
    qRegisterMetaType<Color>("Color");
    qDBusRegisterMetaType<Color>();
}

Client Side

Include generated calculatorInterface.h and enums.h in your main.cpp.

Now you can simply call your method:

int main(int argc, char** argv)
{
    qRegisterMetaType<Color>("Color");
    qDBusRegisterMetaType<Color>();

    QDBusConnection dbus = QDBusConnection::sessionBus();

    com::meJ::system::CalculatorInterface *calculator = new com::meJ::system::CalculatorInterface("com.meJ.system", "/Calc", dbus);
    if (calculator->isValid() == false) {
        cerr << "ERROR: " << qPrintable(calculator->lastError().message()) << endl;
        exit(1);
    }

    Color c = GREEN;
    calculator->setColor(c);
    std::cout << qPrintable(calculator->lastError().message()) << std::endl;

    exit(0);
}

If everything worked you should see following output at your server program:

~# Color: green

OTHER TIPS

Here is my solution which uses macro and does not have boost dependency. You need to write below statement in your header file to declare << and >> operators.

For example:

DECLARE_ENUM_DATATYPE(QProcess::ProcessState)

and in one .cpp file add below statement to define << and >> operators.

CREATE_ENUM_DATATYPE(QProcess::ProcessState)

Both above functions require below file, you can save it as enumDBus.hpp

#ifndef _ENUM_DBUS_HPP
#define _ENUM_DBUS_HPP

#include <QtDBus/QDBusArgument>

#define DECLARE_ENUM_DATATYPE(ENUM_TYPE_DBUS)\
     QDBusArgument &operator<<(QDBusArgument &argument, ENUM_TYPE_DBUS value);\
     const QDBusArgument &operator>>(const QDBusArgument &argument, ENUM_TYPE_DBUS &val);


#define CREATE_ENUM_DATATYPE(ENUM_TYPE_DBUS)\
     QDBusArgument &operator<<(QDBusArgument &argument, ENUM_TYPE_DBUS value)\
     {\
         argument.beginStructure();\
         qlonglong newVal = (qlonglong)value;\
         argument << newVal;\
         argument.endStructure();\
         return argument;\
     }\
     const QDBusArgument &operator>>(const QDBusArgument &argument, ENUM_TYPE_DBUS &val)\
     {\
         argument.beginStructure();\
         qlonglong result = 0;\
         argument >> result;\
         val = (ENUM_TYPE_DBUS)result;\
         argument.endStructure();\
         return argument;\
     }

#endif //_ENUM_DBUS_HPP
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top