[SOLVED] Strange error when extending QObject



  • I have strange error.

    If I extend my class with QObject (with setting Q_OBJECT macro), then I try to create that class in main function, I get this error at runtime/startup: The program has unexpectedly finished.
    If I run debugger, it shows me this error code: 0xc0000135 (I googled about it, and it seems that is missing some DLL file).
    I tried to run Dependency Walker, but he complains that some ieshims.dll file is missing (even when application is working, so I wouldn't trust to that, but I wanted to mention).

    However, if I comment those 2 lines, I get perfectly running class (printing out "A" and "B").

    This is my class:
    @#ifndef FIELD_H
    #define FIELD_H

    #include "essentials_global.h"

    #include <QObject>
    #include <QMap>

    class ESSENTIALSSHARED_EXPORT Field// : public QObject
    {
    //Q_OBJECT
    private:
    QMap< int, QMap< int, int > * > * field = new QMap< int, QMap< int, int > * >();
    int columns = 0, rows = 0;

    public:
    Field()
    {
    qDebug("A");
    Field(0, 0);
    qDebug("B");
    }

    Field(int columns, int rows)
    {
    this->columns = columns;
    this->rows = rows;
    for (int i=0; i<columns; i++)
    field->insert(i, new QMap<int, int>());
    }
    };

    #endif // FIELD_H@

    Can someone tell me why is this problem?

    I need to extend QObject since I want to use it in QML (needed for qmlRegisterType function).

    I want to note that this class is in DLL library, and it is imported in application.
    Also, I have other classes that extend QObject and they are fine (though they are in different DLL).

    I am suspecting that something is wrong with .pro file, but I cannot figure out (if needed I will provide).


  • Lifetime Qt Champion

    Hi,

    I don't have a windows machine at hand but something that puzzles me:
    Doesn't your compiler complain about the "field" variable initialization ?



  • You are missing a constructor call of parent class.
    @ explicit Field() : QObject()
    {
    // some code
    }
    @

    Also, it is a bad idea to call a constructor from another constructor. It can create a lot of problems like multiple initializations of parent properties etc.



  • That is strage part, it doesn't complain at all.
    I tried to put qDebug("ASD"); in very first line in main function but it doesn't output "ASD", just that error.

    I have tried also to put Field() : QObject() but problem remains.
    I also have working classes that extend QObject but not call QObject at constructor, so I doubt that this is issue.

    Thanks for helping me out


  • Lifetime Qt Champion

    Even if it doesn't, move that in your constructor, it's one less thing that might be problematic.

    I would also suggest to rather use:
    @
    explicit Field(int columns = 0, int rows = 0)
    {
    this->columns = columns;
    this->rows = rows;
    for (int i=0; i<columns; i++)
    field->insert(i, new QMap<int, int>());
    }@

    One less constructor and as toptan said, in c++ you don't call constructor from constructor. If you really want to have multiple constructor, add a private initialization function that does everything needed.


  • Moderators

    There's an inheriting constructor in C++11, but the syntax is different and I don't think any compiler is implementing it yet.
    Field(0, 0) does not initialize the "surrounding" object. It just creates another, temporary object that is immediately destroyed.

    As for the main problem - ieshims.dll is a bogus warning so don't worry about it. Since your dll creates something QObject based make sure that you have the required Qt dlls (in your case this would be at least QtCore) in the same location as your dll.



  • But I have tried to remove Field() constructor and make other one as SGaist suggested, and I am still having this issue. If I remove QObject extending it runs without problems.

    Runs:
    @class ESSENTIALSSHARED_EXPORT Field// : public QObject
    {
    // Q_OBJECT
    private:
    QMap< int, QMap< int, int > * > * field = new QMap< int, QMap< int, int > * >();
    int columns = 0, rows = 0;

    public:
    explicit Field(int columns = 0, int rows = 0) //: QObject()
    {
    this->columns = columns;
    this->rows = rows;
    field = new QMap< int, QMap< int, int > * >();
    for (int i=0; i<columns; i++)
    field->insert(i, new QMap<int, int>());
    }
    };@

    Does not run:
    @class ESSENTIALSSHARED_EXPORT Field : public QObject
    {
    Q_OBJECT
    private:
    QMap< int, QMap< int, int > * > * field = new QMap< int, QMap< int, int > * >();
    int columns = 0, rows = 0;

    public:
    explicit Field(int columns = 0, int rows = 0) : QObject()
    {
    this->columns = columns;
    this->rows = rows;
    field = new QMap< int, QMap< int, int > * >();
    for (int i=0; i<columns; i++)
    field->insert(i, new QMap<int, int>());
    }
    };@

    Is it possible that this is bug in Qt?



  • I have tried to make plain class.

    Runs:
    @class ESSENTIALSSHARED_EXPORT Field
    {
    public:
    explicit Field()
    {
    }
    };@

    Does not run:
    @class ESSENTIALSSHARED_EXPORT Field : public QObject
    {
    Q_OBJECT

    public:
    explicit Field() : QObject()
    {
    }
    };@

    So I think now that this is Qt bug.

    I have tried also to remove build directories and recompile everything, but problem remains same.


  • Moderators

    Quite a lot of software out there would be broken if there was a bug preventing from inheriting QObject, and I think one or two guys would stumble upon it before release, don't you think? :)

    If it compiles without errors or warnings then it's probably a deployment problem, not an implementation one. Give a Dependency Walker another run, but this time use the Profile feature (F7) to check for runtime dependencies. If you just use "open" it shows only the statically linked libraries and doesn't show dynamic ones like platform plugins etc. It will also show you which libraries and from what locations it is picking up and what is missing.



  • Tanks Chris, you were right.
    It is missing library nameD.dll, but I have putted in my project to search name.dll (as it was named).
    For some reason, I must name it nameD.dll when I am inheriting QObject and then it works.

    I am curious why is that? Without QObject it runs without issues.
    That is only part I change in code (no library paths redefining or similar).

    Thanks all for helping me


  • Moderators

    Great, glad I could help.
    D is for Debug. You should have both D and non-D Qt libraries in your Qt installation.

    Make sure you don't mix release and debug libraries and executables. Everything in your app should be "the same kind". This means the executable (.exe), Qt dlls and your own libraries.


Log in to reply
 

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