Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Nullpointer passed when using pointer to const object as parameter for c++ method called from qml
Forum Updated to NodeBB v4.3 + New Features

Nullpointer passed when using pointer to const object as parameter for c++ method called from qml

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 2.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AlaNan
    wrote on last edited by
    #1

    Consider the following minimal example:
    main.cpp

    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QtQml>
    #include "test.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        qmlRegisterType<Test>("nanotron.test.test", 1, 0, "Test");
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        return app.exec();
    }
    
    

    test.h

    #ifndef TEST_H
    #define TEST_H
    
    #include <QObject>
    
    class Test : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int member MEMBER m_member NOTIFY memberChanged)
    public:
        explicit Test(QObject *parent = 0);
        Q_INVOKABLE void print(const Test* other);
    
    signals:
        void memberChanged();
    
    public slots:
    
    private:
        int m_member;
    };
    
    Q_DECLARE_METATYPE(const Test*)
    #endif // TEST_H
    
    

    test.cpp

    #include "test.h"
    #include <QDebug>
    
    Test::Test(QObject *parent) : QObject(parent)
    {
    }
    
    void Test::print(const Test *other)
    {
        qWarning() << "Value of test object's meber:" << other->m_member;
    }
    

    main.qml

    import QtQuick 2.5
    import QtQuick.Controls 1.4
    import nanotron.test.test 1.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Component {
            id: testComponent
            Test {
            }
        }
    
        menuBar: MenuBar {
            Menu {
                title: qsTr("File")
                MenuItem {
                    text: qsTr("&Open")
                    onTriggered: {
                        var test1 = testComponent.createObject()
                        var test2 = testComponent.createObject()
                        test1.member = 4711
                        test2.print(test1)
                    }
                }
                MenuItem {
                    text: qsTr("Exit")
                    onTriggered: Qt.quit();
                }
            }
        }
    
        Label {
            text: qsTr("Hello World")
            anchors.centerIn: parent
        }
    }
    

    When I run this and click on File -> Open the program crashes. In the debugger I can see that NULL is passed to the print method of the test class. I can trace it back to the qt_metacall method of the moc class that is generated for test.
    When I remove the const from the parameter in print, i.e change

    Q_INVOKABLE void print(const Test* other);
    

    to

    Q_INVOKABLE void print(Test* other);
    

    and

    void Test::print(const Test *other)
    

    to

    void Test::print(Test *other)
    

    and

    Q_DECLARE_METATYPE(const Test*)
    

    to

    Q_DECLARE_METATYPE(Test*)
    

    it works fine.

    Can someone explain this to me? Is it a bug? Is it expected? Is it possible to use pointers to const objects when passing parameters from QML to c++?

    A 1 Reply Last reply
    0
    • A AlaNan

      Consider the following minimal example:
      main.cpp

      #include <QApplication>
      #include <QQmlApplicationEngine>
      #include <QtQml>
      #include "test.h"
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
          qmlRegisterType<Test>("nanotron.test.test", 1, 0, "Test");
          QQmlApplicationEngine engine;
          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
          return app.exec();
      }
      
      

      test.h

      #ifndef TEST_H
      #define TEST_H
      
      #include <QObject>
      
      class Test : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(int member MEMBER m_member NOTIFY memberChanged)
      public:
          explicit Test(QObject *parent = 0);
          Q_INVOKABLE void print(const Test* other);
      
      signals:
          void memberChanged();
      
      public slots:
      
      private:
          int m_member;
      };
      
      Q_DECLARE_METATYPE(const Test*)
      #endif // TEST_H
      
      

      test.cpp

      #include "test.h"
      #include <QDebug>
      
      Test::Test(QObject *parent) : QObject(parent)
      {
      }
      
      void Test::print(const Test *other)
      {
          qWarning() << "Value of test object's meber:" << other->m_member;
      }
      

      main.qml

      import QtQuick 2.5
      import QtQuick.Controls 1.4
      import nanotron.test.test 1.0
      
      ApplicationWindow {
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
      
          Component {
              id: testComponent
              Test {
              }
          }
      
          menuBar: MenuBar {
              Menu {
                  title: qsTr("File")
                  MenuItem {
                      text: qsTr("&Open")
                      onTriggered: {
                          var test1 = testComponent.createObject()
                          var test2 = testComponent.createObject()
                          test1.member = 4711
                          test2.print(test1)
                      }
                  }
                  MenuItem {
                      text: qsTr("Exit")
                      onTriggered: Qt.quit();
                  }
              }
          }
      
          Label {
              text: qsTr("Hello World")
              anchors.centerIn: parent
          }
      }
      

      When I run this and click on File -> Open the program crashes. In the debugger I can see that NULL is passed to the print method of the test class. I can trace it back to the qt_metacall method of the moc class that is generated for test.
      When I remove the const from the parameter in print, i.e change

      Q_INVOKABLE void print(const Test* other);
      

      to

      Q_INVOKABLE void print(Test* other);
      

      and

      void Test::print(const Test *other)
      

      to

      void Test::print(Test *other)
      

      and

      Q_DECLARE_METATYPE(const Test*)
      

      to

      Q_DECLARE_METATYPE(Test*)
      

      it works fine.

      Can someone explain this to me? Is it a bug? Is it expected? Is it possible to use pointers to const objects when passing parameters from QML to c++?

      A Offline
      A Offline
      AlaNan
      wrote on last edited by
      #2

      Come on!
      Nobody any idea?
      What could be the reason for changing a valid pointer to a null pointer on the callers side when the signature of the parameter is const ptr??
      Is it just me?
      Can anybody reproduce this???

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi and welcome to devnet,

        You should use qmlRegisterType<const Test>("nanotron.test.test", 1, 0, "Test");

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AlaNan
          wrote on last edited by
          #4

          Thank you very much!
          I guessed it must be something trivial. Of course I have to register the exact type that I want to use with the meta type system.
          I'm not sure if like the fact that registering the wrong type leads to a null pointer being passed. Do you happen to know what is the reason for that? Is it the unchecked result of a dynamic cast? I certainly would prefer, if an exception could be raised in that case. Do you think this would be possible to add?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            You're welcome !

            No I don't, sorry, I haven't touched the internals of the QtQuick/QML modules.

            That's a question you should bring to the interest mailing list. You'll find there Qt's developers/maintainers(this forum is more user oriented)

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved