QtDBUS: отправлять Enums через DBUS

Я использую привязку qt dbus в C ++.

В настоящее время я могу отправлять любые пользовательские типы (например, класс, структуры) через dbus, но я не могу отправить перечисление.

Я тоже пробовал эту ссылку здесь, но я не понимаю

4

Решение

Я нашел решение для моей проблемы:

Сначала создайте новый заголовочный файл с именем enums.h который выглядит как:

#ifndef ENUMS_H
#define ENUMS_H

#include <QtDBus>
#include "enumDBus.h"
enum Color {
RED = 0,
BLUE,
GREEN
};

Q_DECLARE_METATYPE(Color)

#endif  /* ENUMS_H */

Обратите внимание на следующую строку #include "enumDBus.h"Вы можете найти этот заголовочный файл Вот.

Поэтому после того, как вы объявили enum, вы можете объявить метод, который принимает enum в качестве аргумента, в этом примере я объявил следующий метод в calculator.h:

void setColor(Color color);

Реализация для этого метода:

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;
}
}

Теперь давайте сгенерируем описание интерфейса (XML), используя следующую команду

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

Генерация метода, содержащего пользовательские типы, не работает должным образом, поэтому нам нужно внести некоторые коррективы:

<!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>

С помощью этого XML-файла мы можем просто создавать наши классы адаптеров и интерфейсов.

В нашем main.cpp (на клиенте и сервере!) мы должны зарегистрировать наш пользовательский тип:

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

Сторона клиента

Включить сгенерированный calculatorInterface.h а также enums.h в вашем main.cpp,

Теперь вы можете просто вызвать свой метод:

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);
}

Если все работает, вы должны увидеть следующий вывод в вашей серверной программе:

~# Color: green
3

Другие решения

Вот мое решение, которое использует макрос и не имеет буст-зависимости.
Вы должны написать ниже заявление в заголовочном файле, чтобы объявить << и >> операторы.

Ex.

DECLARE_ENUM_DATATYPE(QProcess::ProcessState)

и в одном файле .cpp добавьте ниже заявление, чтобы определить << и >> операторы.

CREATE_ENUM_DATATYPE(QProcess::ProcessState)

Обе вышеперечисленные функции требуют ниже файла, вы можете сохранить его как 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
1

По вопросам рекламы [email protected]