Q_INVOKABLE method returns a QObject-derived type, segfault happens, but why?



  • I've made a small test case for this. It doesn't appear to matter if I use qmlRegisterType or if I construct the object normally and expose it via setContextProperty, the result is the same.

    Here's the QML:

    [code]import QtQuick 1.1

    Rectangle {
    width: 360
    height: 360
    Text {
    text: qsTr("Hello World")
    anchors.centerIn: parent
    }
    MouseArea {
    anchors.fill: parent
    onClicked: {
    var x = testClass.getContainer(1.23, "Hello, world.");
    }
    }
    }
    [/code]

    Here's testClass and ContainerClass:

    [code]class ContainerClass : public QObject
    {
    Q_OBJECT

    QObject     *m_parent;
    

    public:
    ContainerClass(QObject *p=NULL)
    : QObject(p)
    {}

    ContainerClass(const ContainerClass &other)
        : QObject(other.m_parent)
    {
        copyFrom(&other);
    }
    
    ContainerClass operator=(const ContainerClass &other)
    {
        copyFrom(&other);
        return *this;
    }
    
    void copyFrom(const ContainerClass *other)
    {
        m_parent    = other->m_parent;
        m_number    = other->m_number;
        m_string    = other->m_string;
    }
    
    double      m_number;
    QString     m_string;
    

    };

    class TestClass : public QObject
    {
    Q_OBJECT
    public:
    explicit TestClass(QObject *parent = 0);

    public slots:
    Q_INVOKABLE ContainerClass getContainer(double number, QString string);
    };
    [/code]

    Where getContainer is:

    [code]ContainerClass TestClass::getContainer(double number, QString string)
    {
    ContainerClass c;
    c.m_number = number;
    c.m_string = string;
    return c;
    }
    [/code]

    And here's a backtrace:

    [code]0 QString::operator= qstring.cpp 1411 0x7ffff6754bc0
    1 ContainerClass::copyFrom testclass.h 33 0x40448f (corresponds to line 28 in copyFrom on my paste)
    2 ContainerClass::operator= testclass.h 25 0x40442b
    3 TestClass::qt_static_metacall moc_testclass.cpp 112 0x40422b
    4 TestClass::qt_metacall moc_testclass.cpp 151 0x404370
    5 QDeclarativeObjectMethodScriptClass::callMethod qdeclarativeobjectscriptclass.cpp 970 0x7ffff7a8ae8b
    6 QDeclarativeObjectMethodScriptClass::callPrecise qdeclarativeobjectscriptclass.cpp 944 0x7ffff7a8cb28
    7 QDeclarativeObjectMethodScriptClass::call qdeclarativeobjectscriptclass.cpp 917 0x7ffff7a8d5eb
    8 ?? /usr/lib/x86_64-linux-gnu/libQtScript.so.4 0 0x7ffff5b16e09
    9 ?? /usr/lib/x86_64-linux-gnu/libQtScript.so.4 0 0x7ffff5a1791e
    10 ?? /usr/lib/x86_64-linux-gnu/libQtScript.so.4 0 0x7ffff59ee5e6
    11 ?? 0 0x7ffff7e0decd
    12 ?? 0
    [/code]

    Now, I have put little printfs in the constructors and copyFrom method and have sorted out that the meta object code is trying to copy a valid ContainerClass into a pointer cast as a ContainerClass which hasn't been constructed properly. (I only see my constructor called once, which is done by getContainer initially.)

    I can't find anything in the documentation I've read which states that this shouldn't just work.

    I can use QObject properties if needed, but I'd rather be able to use custom types of course.

    So what am I doing wrong here?

    Thanks all!



  • The return type from the invokable function should be a pointer.



  • Yeah that makes sense, thanks.


  • Moderators

    As chriadam said + be sure to read "QObject":http://qt-project.org/doc/qt-4.8/QObject.html documentation, especially that part:
    QObject has neither a copy constructor nor an assignment operator. This is by design. Actually, they are declared, but in a private section with the macro Q_DISABLE_COPY(). In fact, all Qt classes derived from QObject (direct or indirect) use this macro to declare their copy constructor and assignment operator to be private. The reasoning is found in the discussion on Identity vs Value on the Qt Object Model page.


Log in to reply
 

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