Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Problem with compile class with QObject



  • Hi,

    I have created the MqttClient class. While building the program, got strange errors, including "undefined reference to 'vtable for QMqttClient". I solved the problem by clicking:
    "Clean all" -> "Run qmake" -> "Build all"
    The program was building. Unfortunately, when I create an MqttClient object in main cpp, I get a lot of errors (35) starting with "undefined reference to 'QMqttClient::......"
    For example:

    error: undefined reference to `QMqttClient::QMqttClient(QObject*)'
    error: undefined reference to `QMqttTopicFilter::~QMqttTopicFilter()'
    error: undefined reference to `vtable for QMqttClient'
    
    /home/jakub/raspi/qt5pi/include/QtCore/qobject.h:269: error: undefined reference to `QMqttClient::staticMetaObject'
    
    error: undefined reference to `QMqttClient::qt_metacast(char const*)'
    error: undefined reference to `typeinfo for QMqttClient'
    

    Another "Clean all" -> "Run qmake" -> "Build all" doesnt fix the errors. I also tried removing the moc files from the build folder and it didnt help. What can I do?

    Below is my class and pro file (I'm using cross compilation for RPi4)

    Header:

    #ifndef MQTTCLIENT_H
    #define MQTTCLIENT_H
    
    #include <QtMqtt/QMqttClient>
    #include <QtMqtt/QMqttSubscription>
    #include "../UserApp/config.h"
    
    class MqttClient : public QMqttClient
    {
        Q_OBJECT
    public:
        MqttClient(QObject *parent = nullptr);
        ~MqttClient(){}
    
    private:
        QMqttClient *m_mqttClient;
    
    signals:
        void newMotorsCommand(MotorsCommand &motorsCommand);
    
    private slots:
        void slotErrorChanged(const QMqttClient::ClientError e);
        void slotStateChanged();
        void slotDisconnected();
        void slotConnected();
    };
    
    #endif // MQTTCLIENT_H
    

    CPP file:

    #include "mqttclient.h"
    
    MqttClient::MqttClient(QObject *parent) : QMqttClient(parent)
    {
        m_mqttClient = new QMqttClient();
    
        if (m_mqttClient) {
          m_mqttClient->setHostname("localhost");
          m_mqttClient->setPort(1883);
          m_mqttClient->setUsername("guest");
          m_mqttClient->setPassword("guest");
    
          connect(m_mqttClient, &QMqttClient::stateChanged, this, &MqttClient::slotStateChanged);
          connect(m_mqttClient, &QMqttClient::disconnected, this, &MqttClient::slotDisconnected);
          connect(m_mqttClient, &QMqttClient::connected, this, &MqttClient::slotConnected);
          connect(m_mqttClient, &QMqttClient::errorChanged, this, &MqttClient::slotErrorChanged);
    
          m_mqttClient->connectToHost();
        }
    }
    
    void MqttClient::slotConnected()
    {
      qDebug() << Q_FUNC_INFO;
    
      auto sub = m_mqttClient->subscribe(QMqttTopicFilter(MQTT::TRUCK::MOTORS_TOPIC), 0);
    
      m_mqttClient->connect(sub, &QMqttSubscription::messageReceived, [this](const QMqttMessage &message) {});
    }
    
    void MqttClient::slotDisconnected()
    {
      qDebug() << Q_FUNC_INFO;
    }
    
    void MqttClient::slotStateChanged()
    {
      const QString content = QDateTime::currentDateTime().toString()
          + QLatin1String(": State Change : ")
          + QString::number(m_mqttClient->state());
      qDebug() << Q_FUNC_INFO << content;
    }
    
    void MqttClient::slotErrorChanged(const QMqttClient::ClientError e)
    {
      if (e == QMqttClient::NoError) {
        return;
      }
    
      qDebug() << Q_FUNC_INFO;
      switch (e) {
        case QMqttClient::NoError                :  qDebug() << "NoError"; break;
        case QMqttClient::InvalidProtocolVersion :  qDebug() << "InvalidProtocolVersion";break;
        case QMqttClient::IdRejected             :  qDebug() << "IdRejected";break;
        case QMqttClient::ServerUnavailable      :  qDebug() << "ServerUnavailable";break;
        case QMqttClient::BadUsernameOrPassword  :  qDebug() << "BadUsernameOrPassword";break;
        case QMqttClient::NotAuthorized          :  qDebug() << "NotAuthorized";break;
        case QMqttClient::TransportInvalid       :  qDebug() << "TransportInvalid";break;
        case QMqttClient::ProtocolViolation      :  qDebug() << "ProtocolViolation";break;
        case QMqttClient::UnknownError           :  qDebug() << "UnknownError"; break;
        case QMqttClient::Mqtt5SpecificError     :  qDebug() << "Mqtt5SpecificError";break;
      }
    
      qWarning() << "Error Occurred:" << e << " Client state :" << m_mqttClient->state();
      m_mqttClient->disconnectFromHost();
    }
    

    PRO:

    QT -= gui mqtt
    
    CONFIG += c++11 console
    CONFIG -= app_bundle
    
    DEFINES += QT_DEPRECATED_WARNINGS
    
    INCLUDEPATH += /home/jakub/raspi/sysroot/usr/include/
    
    LIBS += -L"/home/jakub/raspi/sysroot/usr/lib"
    LIBS += -lwiringPi -lpthread
    
    SOURCES += \
            main.cpp \
            mqtt/mqttclient.cpp
    
    HEADERS += \
        ../common/msg_structures.h \
        mqtt/mqttclient.h
    
    target.path = /home/pi/UDES/bin
    INSTALLS += target
    
    

  • Lifetime Qt Champion

    Hi,

    You explicitly disable the gui and mqtt modules in your .pro file.



  • @SGaist It's works! Thank you!


Log in to reply