Using signals and slots in a derived class from AbstractSerial (QSerialDevice)



  • Hi, I'm having some trouble with QSerialDevice or something ... I don't even know where to look.
    In my project, I derived a class from AbstractSerial from the QSerialDevice library (version 0.4). It's really basic:

    Port.h
    @#ifndef PORT_H
    #define PORT_H

    #include "qserialdevice/abstractserial.h"

    class Port : public AbstractSerial
    {
    Q_OBJECT

    private:
        bool ready;
    
    public:
        explicit Port( QObject* parent = 0 );
        ~Port();
    
    public slots:
    

    };

    #endif // PORT_H
    @

    Port.cpp
    @#include "Port.h"

    Port::Port( QObject* parent ) : AbstractSerial( parent )
    {
    ready = false;
    }
    @

    And yet, simply adding this class in my project makes the build fail. With the code above, here's errors I get in the compile output :
    @c:/qtsdk/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has been activated without --enable-auto-import specified on the command line.
    This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.
    ./debug/obj/moc_Port.o:moc_Port.cpp:(.rdata$_ZTV4Port[vtable for Port]+0x14): undefined reference to Port::~Port()' Info: resolving AbstractSerial::staticMetaObject by linking to __imp___ZN14AbstractSerial16staticMetaObjectE (auto-import) mingw32-make.exe[1]: Leaving directoryC:/dev/projects/EyeCheck'
    ./debug/obj/moc_Port.o:moc_Port.cpp:(.rdata$_ZTV4Port[vtable for Port]+0x18): undefined reference to `Port::~Port()'
    collect2: ld returned 1 exit status
    mingw32-make.exe[1]: *** [debug/EyeCheckDebug.exe] Error 1
    mingw32-make.exe: *** [debug] Error 2
    12:01:46: The process "C:\QtSDK\mingw\bin\mingw32-make.exe" exited with code 2.
    Error while building project EyeCheck (target: Desktop)
    When executing build step 'Make'@

    And if I remove the Q_Object from Port.h, I get that:
    @./debug/obj/Port.o: In function Port': C:\dev\projects\EyeCheck/Port.cpp:3: undefined reference tovtable for Port'
    C:\dev\projects\EyeCheck/Port.cpp:3: undefined reference to vtable for Port' collect2: ld returned 1 exit status mingw32-make.exe[1]: Leaving directoryC:/dev/projects/EyeCheck'
    mingw32-make.exe[1]: *** [debug/EyeCheckDebug.exe] Error 1
    mingw32-make.exe: *** [debug] Error 2
    12:09:17: The process "C:\QtSDK\mingw\bin\mingw32-make.exe" exited with code 2.
    Error while building project EyeCheck (target: Desktop)
    When executing build step 'Make'@

    I really don't know what's wrong... If anyone could help me, that'd be great !




  • Moderators

    Two things:
    You are using QSerialDevice version 0.4. This version seems to be quite old.
    Where is your implementation of the destructor?
    You do not show the implementation of ~Port() and the first output is complaining this destructor is missing.



  • -koahnig: Well that destructor was the problem... I can't believe I didn't see that... I tried so many things that I guess I skipped the most basics. Thanks !-

    kuzulis: I actually took a quick look, but it looks like lots of stuff changed. That would mean refactoring my entire project and it seems like the device enumerator is gone, and that's a feature I need. The version 0.4 is working fine for now, so I'll stick with that. I might take another look later, but for now I'd rather stick with something functionnal.

    EDIT: Actually it doesn't work. I had removed the Q_OBJECT for testing, so while implementing the destructor in the cpp did make it build, I still have some problem with the Q_OBJECT. My app builds, but when I run I get get this before getting to the main window :
    @The program has unexpectedly finished.
    C:\dev\projects\EyeCheck\debug\EyeCheckDebug.exe exited with code -1073741819@

    Google didn't get me any answer as to what that means, so I don't really know what I should look for... I do get a warning when building, I don't know if it could be related :
    @:-1: warning: auto-importing has been activated without --enable-auto-import specified on the command line.@

    Here's my code from the main window (slot_deviceIsReady() only do some UI stuff):
    @void MainWindow::openPort( QString name )
    {
    port = new Port( name );

    if( port->open( QIODevice::ReadWrite ) ) // if connection is successful
    {
        connected = true;
    
        port->setBaudRate( settings->bps[ settings->value("bitsPerSecond").toString() ] );
        port->setDataBits( settings->dataBits[ settings->value("dataBits").toString() ] );
        port->setParity( settings->parity[ settings->value("parity").toString() ] );
        port->setStopBits( settings->stopBits[ settings->value("stopBits").toString() ] );
        port->setFlowControl( settings->flowControl[ settings->value("flowControl").toString() ] );
    
        connect( port, SIGNAL( readyRead() ), port, SLOT( dataAvailable() ) );
        connect( port, SIGNAL( deviceIsReady() ), this, SLOT( slot_deviceIsReady() ) );
        display( "Connected to " + name );
        display( "Waiting for Ready..." );
        port->write("?;");
    }
    else
    {
        display( "Port could not be opened." );
    }
    

    }@

    Port.h
    @#ifndef PORT_H
    #define PORT_H

    #include "qserialdevice/abstractserial.h"

    class Port : public AbstractSerial
    {
    Q_OBJECT

    private:
        bool ready;
    
    public:
        Port( QString name, QObject* parent = 0 );
        bool isReady() const;
        void setReady( bool state );
    
    signals:
        void deviceIsReady();
    
    public slots:
        void dataAvailable();
    

    };

    #endif // PORT_H
    @

    Port.cpp
    @#include "Port.h"

    Port::Port( QString name, QObject* parent ) : AbstractSerial( parent )
    {
    setDeviceName( name );
    ready = false;
    }

    void Port::setReady( bool state )
    {
    ready = state;
    }

    bool Port::isReady() const
    {
    return ready;
    }

    void Port::dataAvailable()
    {
    QByteArray ba;
    ba.clear();
    ba = read( bytesAvailable() );

    if( ba == "Ready" )
    {
        ready = true;
    
        emit deviceIsReady();
    }
    

    }
    @



  • 2 Shabla,

    We have already mentioned that 0.4 is outdated and no longer supported. Therefore, all the errors for the 0.4 you will have to correct myself. Version 2.0 is not very different from the 0.4 - and I advise you to take 2.0, the more that 2.0 adopted in Qt as addon (read on QSerialDevice wiki on gitorious). And in the future, it will be a 2.0 base starting point for further development and support.

    So, in your question, I can not help.


  • Moderators

    [quote author="Shabla" date="1330628949"]-koahnig: Well that destructor was the problem... I can't believe I didn't see that... I tried so many things that I guess I skipped the most basics. Thanks !-

    EDIT: Actually it doesn't work. I had removed the Q_OBJECT for testing, so while implementing the destructor in the cpp did make it build, I still have some problem with the Q_OBJECT. My app builds, but when I run I get get this before getting to the main window :
    @The program has unexpectedly finished.
    C:\dev\projects\EyeCheck\debug\EyeCheckDebug.exe exited with code -1073741819@

    [/quote]
    Since your error changed substancially the destructor was missing. However, you have now a run time error.

    As kurzulis has already repeated your version is old. My suggestion would be to bite the bullet and check how to chaneg to the most recent version of QSerialDevice.



  • Aight I did as proposed and switched to 2.0. Not as many changes as I though, and I can manage with SerialPortInfo instead of the COM enumerator.

    However, I still have the same problem. I use the same class as above (Port) derived from SerialPort instead of AbstractSerial. Without this class Port, everything works, no warnings, no errors. With this class Port, I can build successfully, but I get this in my compile output :
    @c:/qtsdk/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has been activated without --enable-auto-import specified on the command line.
    This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.
    15:42:19: The process "C:\QtSDK\mingw\bin\mingw32-make.exe" exited normally.@

    If I try to run the application, I can't even get to the main window, I get an error code 0xc0000005.
    I compile with gcc via Qt Creator, on Windows XP

    Here's my .pro :
    @TEMPLATE = app
    DEPENDPATH += .
    INCLUDEPATH += .

    HEADERS += HelpWidget.h
    MainWindow.h
    MenuAbout.h
    MenuSequence.h
    MenuSettings.h
    PortSettings.h
    Regex.h
    ThreadSequence.h
    Port.h

    FORMS += HelpWidget.ui
    MainWindow.ui
    MenuAbout.ui
    MenuSequence.ui
    MenuSettings.ui

    SOURCES += HelpWidget.cpp
    main.cpp
    MainWindow.cpp
    MenuAbout.cpp
    MenuSequence.cpp
    MenuSettings.cpp
    PortSettings.cpp
    ThreadSequence.cpp
    Port.cpp

    RESOURCES += ressources.qrc

    INCLUDEPATH += "C:/dev/libs/qserialdevice-2.0/include"

    DEBUG

    CONFIG += debug
    OBJECTS_DIR = debug/obj
    MOC_DIR = debug/moc
    LIBS += -L"C:/dev/libs/qserialdevice-2.0/src/debug" -lSerialPort
    TARGET = EyeCheckDebug

    RELEASE

    #CONFIG += release
    #OBJECTS_DIR = release/obj
    ##MOC_DIR = release/moc
    #LIBS += -L"C:/dev/libs/qserialdevice-0.4/src/build/release" -lqserialdevice
    #TARGET = EyeCheck
    @


  • Moderators

    Can you identify some macro causing the warning you are posting?

    Do I get you right that this warning is coming only when you are using your Port class?



  • I'm not sure I understand the first question, but that's right for the second one.

    After some more research, I "found":http://stackoverflow.com/questions/8375310/warning-auto-importing-has-been-activated-without-enable-auto-import-specifie that "This is a MingW specific warning telling you that several dynamic libraries are being linked in implicitly."

    I don't know why I only get this warning with my Port class, as I was already using the SerialPort class in my app before. My uneducated guess is that something is wrong with the linking process. I'll keep searching, need to get this working.



  • 2 Shabla

    First, try to build the library and application - and after, copy the *.dll the library in a directory with an executable application file *.exe.

    And after that execute the application.



  • It gives me the same error ("The application failed to initialize properly (0xc0000005). Click on OK to terminate the application."). Tested on the debug version with the dlls the .exe asked for :
    App.exe
    SerialPort.dll
    QtCored4.dll
    QtGuid4.dll



  • I made a new project with only a MainWindow and a Port class (the same from my other project).
    Eveything works until I add Q_OBJECT, signals and slots. When I add those, I get the same warning, and the same error code when I try to run the app.

    Is there anything needed (like include or libs or something like that) in order to use signals and slots of Qt ? Because currently the only include in my Port.h is
    @#include "serialport.h"@



  • Alright, so I didn't find the problem, but I found a solution. Instead of deriving SerialPort in a Port class, my Port class is just a wrapper for SerialPort containing a pointer to my instance of SerialPort and having all the methods I use like that :
    @bool Port::open( SerialPort::OpenMode mode )
    {
    return port->open( mode );

    }@

    I don't know if this is a "good" solution, but it works.

    Anyway, thanks to kuzulis and koahnig for the help ! =)


Log in to reply
 

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