Umgang von QML mit C++ Pointern

C++, Qt, QML

In der Qt-Dokumentation über QML gibt es einen interessanten Abschnitt Data Ownership der sollte in dem Fall beherzigt werden, ansonsten läuft man Gefahr sich ein Memory-Leak zu programmieren.

Was steht dort eigentlich genau beschrieben?

Wenn Daten von C++ nach QML transferiert werden. Dann liegt der Besitz der Daten in C++-Hand. Das wäre zum Beispiel der Fall bei einer Q_PROPERTY.

Q_PROPERTY(int* test READ getTest)

Das heißt, die Daten werden im C++-Code verwaltet und der Speicher muss von dort aus auch verwaltet werden. Alles ist also in Ordnung wenn man sich darum im C++-Code kümmert.

Wenn Allerdings statt einer Q_PROPERTY ein Q_INVOKABLE verwendet wird, kümmert sich QML um die Speicherverwaltung.

Q_INVOKABLE int* getTest();

Diese Funktion liefert an QML einen Pointer auf einen Integer, QML wird den Speicher automatisch wieder freigeben, wenn der Pointer nicht mehr benötigt wird. Wird die Variable im C++-Abschnitt dennoch verwendet führt das zu einem Segmentation Fault. Will man die Ownership wieder in C++ haben gibt es die Möglichkeiten über die Funktionen QQmlEngine::setObjectOwnership() mit QQmlEngine::CppOwnership zu gehen. Möchte man auch bei Q_INVOKABLE grundsätzlich die Ownership behalten, gibt es die Möglichkeit sofern das zurückgegebene Objekt ein Q_OBJECT ist einen Parent-Pointer zu setzen, dieser verhindert das QML das Objekt löscht.