Link errors; Connect a Signal of an object in main.cpp to a Slot in an object in MainWindow.cpp



  • Hi,
    I continue with my effort to run MainWindow in parallel with an old C++ program,
    so I start the MainWindow in a new thread and let the old program in the main thread running (naturly, the old program is here represented for the smal void loop procedure).

    The problem come when I try to comunicate the old program with the gui.

    I only know the signal-> slot method, but it only work with objects I think. With this purpuse I created in main.cpp the SignalSetter object. Theoretically it should make possible the connection between the old programm and the MainWindow gui.

    The problem is that due to Q_OBject macro I think, I obtain the next linker errors

    main.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall SignalSetter::metaObject(void)const " (?metaObject@SignalSetter@@UBEPBUQMetaObject@@XZ)
    main.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall SignalSetter::qt_metacast(char const *)" (?qt_metacast@SignalSetter@@UAEPAXPBD@Z)
    main.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall SignalSetter::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@SignalSetter@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
    main.obj : error LNK2019: unresolved external symbol "public: void __thiscall SignalSetter::emitDistance(double,int)" (?emitDistance@SignalSetter@@QAEXNH@Z) referenced in function "public: __thiscall SignalSetter::SignalSetter(class QObject *)" (??0SignalSetter@@QAE@PAVQObject@@@Z)
    main.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const SignalSetter::staticMetaObject" (?staticMetaObject@SignalSetter@@2UQMetaObject@@B)
    debug\drawRange.exe : fatal error LNK1120: 5 unresolved externals
    

    I don't know if I'm doing the things fine.
    Please, any kind of help will be welcomed

    Thanks in advance
    (here is my code)

    #include "mainwindow.h"
    #include <QApplication>
    #include <thread>
    #include <iostream>
    #include <QObject>
    #include <QDebug>
    
    using namespace std;
    
    static MainWindow *w;
    
    class SignalSetter : public QObject //object to make effective the comunication
    {
        Q_OBJECT
    
    public:
        SignalSetter(QObject *parent = nullptr) : QObject(parent)
        {
            qDebug() << "###################### Connected " << QObject::connect(this, &SignalSetter::emitDistance, w, &MainWindow::setValue) << endl;
        }
        void setDistance(double dst = 0, int barNummer = 1)
        {
            emit emitDistance(dst, barNummer);
        }
    
    signals:
        void emitDistance(double, int);
    
    };
    
    SignalSetter s; //I obtain the link errors  when I define SignalSetter here
    
    
    void guiLoader(int argc, char *argv[]){
        QApplication a(argc, argv);
        w = new MainWindow;
        w->show();
        QApplication::exec();
    }
    
    void loop(){
    
            for(int i = 0; i < 2; i++)
                cerr << "helloworld parallel" << endl;
    
    }
    
    int main(int argc, char *argv[])
    {
        thread guiLoaderThread(guiLoader, argc, argv);
        loop();
        guiLoaderThread.join();                                                             //Last parallel line
        delete w;
        cout << "We wish you a nice day!" << endl;
        return 0;
    }
    
    

  • Moderators

    @Josz
    hi, I‘m unsure what exactly you want to do, as I‘m unfamiliar with guiloader.

    But QObject::connect is a static function, therefore if your emitter is Qobject derived class, you can use it inside main, with the Qt5 syntax, to connect to any function you like.

    Mabe this helps you.



  • @J.Hilk I try to reuse an old communication code. I thought that could raun in paralell with the GUI and make the communication through an object as interface.

    After move "SignalSetter s;" (if I did good understand), I obtain the same links errors like above. :_(

    But thank you very much for help :´-(



  • hello, I have more information,

    When I write the SignalSetter class into 2 separated files (.h & .cpp) and include it on main, work fine!

    But why fails the linker when I simply write the class in main (like is in code showed).
    It seems that everything comes from the macro Q_OBJECT.
    But why?
    Is possible to write in the class main? What should I do?

    Thanks in advance


  • Lifetime Qt Champion

    Hi,

    If you have a QObject defined purely in a cpp file, you have to add:
    #include "cpp_file_name.moc"
    at the end of the file.

    In your case: #include "main.moc"



  • @SGaist Thank you very much!



  • post Info

    #include "main.moc" //must be placed at the end of main.cpp

    To find the main.moc is needed adding in .pro
    INCLUDEPATH += tmp/moc/release_shared


  • Lifetime Qt Champion

    AFAIK, it should not be necessary. Are you modifying other aspects of qmake file generation ?



  • @SGaist said in Link errors; Connect a Signal of an object in main.cpp to a Slot in an object in MainWindow.cpp:

    AFAIK

    I don't know. I have a .pro and a .pri. For me was needed.

    here is my .pro

    QT       += core gui charts
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    TARGET = drawRange
    TEMPLATE = app
    include(drawRangeGUI/drawRangeGUI.pri)
    include(hmisg/hmisg.pri)
    
    INCLUDEPATH += tmp/moc/release_shared
    DEFINES += QT_DEPRECATED_WARNINGS
    CONFIG += c++11
    
    SOURCES += \
            main.cpp
    
    HEADERS +=
    
    FORMS += \
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    DISTFILES += \
        drawRangeGUI/drawrange.pri
    

    and my .pri

    INCLUDEPATH += $$PWD \
                    $$PWD/erpc-1.7.1/erpc_c/port \
                    $$PWD/erpc-1.7.1/erpc_c/infra \
                    $$PWD/erpc-1.7.1/erpc_c/setup \
                    $$PWD/erpc-1.7.1/erpc_c/config \
                    $$PWD/erpc-1.7.1/erpc_c/transports
    
    DEPENDPATH += $$PWD \
                    $$PWD/erpc-1.7.1/erpc_c/port \
                    $$PWD/erpc-1.7.1/erpc_c/infra \
                    $$PWD/erpc-1.7.1/erpc_c/setup \
                    $$PWD/erpc-1.7.1/erpc_c/config \
                    $$PWD/erpc-1.7.1/erpc_c/transports
    
    HEADERS += \
        $$PWD/hmisg.h \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_server_setup.h \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_client_setup.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_basic_codec.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_client_manager.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_codec.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_common.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_crc16.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_framed_transport.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_manually_constructed.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_message_buffer.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_server.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_simple_server.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_transport.h \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_version.h \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_mbf_setup.h \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_transport_setup.h \
        $$PWD/erpc-1.7.1/erpc_c/config/erpc_config.h \
        $$PWD/erpc-1.7.1/erpc_c/port/erpc_config_internal.h \
        $$PWD/erpc-1.7.1/erpc_c/port/erpc_port.h \
        $$PWD/erpc-1.7.1/erpc_c/port/erpc_threading.h \
        $$PWD/erpc-1.7.1/erpc_c/transports/erpc_tcp_transport_win.h
    
    SOURCES += \
        $$PWD/hmisg.cpp \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_server_setup.cpp \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_client_setup.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_basic_codec.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_client_manager.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_crc16.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_framed_transport.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_message_buffer.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_server.cpp \
        $$PWD/erpc-1.7.1/erpc_c/infra/erpc_simple_server.cpp \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_setup_mbf_dynamic.cpp \
        $$PWD/erpc-1.7.1/erpc_c/setup/erpc_setup_tcp.cpp \
        $$PWD/erpc-1.7.1/erpc_c/port/erpc_threading_windows.cpp \
        $$PWD/erpc-1.7.1/erpc_c/transports/erpc_tcp_transport_win.cpp
    
    
    

    regards


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.