0

Consider this example:

ObjectCreator is set as global property via QJSEngine:

// ObjectCreator is exposed to engine_ env as global property
class ObjectCreator : public QObject
{
    Q_OBJECT

public:
    ObjectCreator(QJSEngine * engine, QObject * parent = nullptr) : QObject(parent), engine_(engine) {}
    
    // Called from script env
    Q_INVOKABLE QJSValue createObject();

private:
    
    // engine_ is not owned
    QJSEngine * engine_ = nullptr;
};

class SomeObj : public QObject
{
    // ...
};

QJSValue ObjectCreator::createObject()
{
    // No parent due to JavaScriptOwnership
    return engine_->newQObject(new SomeObj());
}

JavaScript (evaluated in engine_ from previous snippet):

function f
{
        // objectCreator is a global property of engine_
        const someObj = objectCreator.createObj();
}

Reading the documentation I couldn't find an answer to this question:

Is it valid to call engine_->newQObject() in a C++ function that is invoked via a JavaScript-script that is evaluated by engine_?

hannes
  • 1

1 Answers1

0

Yes, it's totally fine for a C++ to call a QJSEngine::newQObject() when called from a script.

The issue you may have is that const is not supported by ECMAScript 5, which is QJSEngine's version (see the explanation at QTBUG-69408). Replace it with var and it should work (though obviously it's not a constant).

Pcgomes
  • 184
  • 7
  • thanks for taking the time! Would you mind pointing me to the respective section in the documentation or source code that covers this (if any)? – hannes Sep 10 '20 at 18:40
  • I don't really understand your doubt `QJSEngine::newQObject()` is a C++ method, and thus can be invoked by any C++ code. Moreover, if the C++ code is exposed to scripts (via `Q_INVOKABLE`, for instance), it's still C++ code, and thus it is completely valid to invoke `newQObject()` There won't be speficic documentation telling that you can create a C++ object from a Javascript invocation because it is follows from the basic premises listed above. Note that you can even call `engine_->newQObject()` from another script object (e.g., `engine_2`) – Pcgomes Sep 13 '20 at 09:56
  • Basically what happens is calling a function of an instance of `QJSEngine` while another function call of this very same instance has not yet returned. Our concern is that this might trigger undefined behavior. – hannes Sep 19 '20 at 07:57