From 94886104f3a9fe43bdb28b4b182024bc63a9744a Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 2 May 2018 00:19:29 +0100 Subject: [PATCH] Prevent the C++ part of PyQt objects being deleted while the Python component is still accessible. --- src/runner/pythonrunner.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/runner/pythonrunner.cpp b/src/runner/pythonrunner.cpp index d987f91..7578949 100644 --- a/src/runner/pythonrunner.cpp +++ b/src/runner/pythonrunner.cpp @@ -499,17 +499,33 @@ struct QClass_converters { struct QClass_to_PyQt { + template + static typename std::enable_if_t, T*> getSafeCopy(T *qClass) + { + return new T(*qClass); + } + + template + static typename std::enable_if_t, T*> getSafeCopy(T *qClass) + { + return qClass; + } + static PyObject *convert(const T &object) { const sipTypeDef *type = sipAPI()->api_find_type(MetaData::className()); if (type == nullptr) { return bpy::incref(Py_None); } - PyObject *sipObj = sipAPI()->api_convert_from_type((void*)(&object), type, 0); + PyObject *sipObj = sipAPI()->api_convert_from_type((void*)getSafeCopy((T*)&object), type, 0); if (sipObj == nullptr) { return bpy::incref(Py_None); } + if (std::is_copy_constructible_v) + // Ensure Python deletes the C++ component + sipAPI()->api_transfer_back(sipObj); + return bpy::incref(sipObj); } @@ -523,11 +539,15 @@ struct QClass_converters return bpy::incref(Py_None); } - PyObject *sipObj = sipAPI()->api_convert_from_type(object, type, 0); + PyObject *sipObj = sipAPI()->api_convert_from_type(getSafeCopy(object), type, 0); if (sipObj == nullptr) { return bpy::incref(Py_None); } + if (std::is_copy_constructible_v) + // Ensure Python deletes the C++ component + sipAPI()->api_transfer_back(sipObj); + return bpy::incref(sipObj); }