From 7a2fed1b755bf8425387be360a8b11d3a77de52d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Fri, 9 Sep 2016 10:46:25 +0200 Subject: [PATCH] Extension: Delete extensions correctly --- src/App/Extension.cpp | 13 ++++++++++++- src/App/ExtensionContainer.cpp | 5 +++++ src/App/ExtensionContainerPyImp.cpp | 2 +- src/App/GroupExtension.cpp | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/App/Extension.cpp b/src/App/Extension.cpp index 845af10de5..e63bfd59cd 100644 --- a/src/App/Extension.cpp +++ b/src/App/Extension.cpp @@ -32,6 +32,7 @@ #include "DocumentObject.h" #include "Base/Exception.h" #include +#include /* We do not use a standart property macro for type initiation. The reason is that we want to expose all property functions, * to allow the derived classes to access the private property data, but we do not want to have our @@ -56,7 +57,17 @@ Extension::Extension() Extension::~Extension() { - + Base::Console().Message("Delete extension\n"); + if (!ExtensionPythonObject.is(Py::_None())){ + // Remark: The API of Py::Object has been changed to set whether the wrapper owns the passed + // Python object or not. In the constructor we forced the wrapper to own the object so we need + // not to dec'ref the Python object any more. + // But we must still invalidate the Python object because it need not to be + // destructed right now because the interpreter can own several references to it. + Base::PyObjectBase* obj = (Base::PyObjectBase*)ExtensionPythonObject.ptr(); + // Call before decrementing the reference counter, otherwise a heap error can occur + obj->setInvalid(); + } } void Extension::initExtension(Base::Type type) { diff --git a/src/App/ExtensionContainer.cpp b/src/App/ExtensionContainer.cpp index bf32d87608..b3329f1181 100644 --- a/src/App/ExtensionContainer.cpp +++ b/src/App/ExtensionContainer.cpp @@ -43,6 +43,11 @@ ExtensionContainer::ExtensionContainer() { ExtensionContainer::~ExtensionContainer() { + //we need to delete all dynamically added extensions + for(auto entry : _extensions) { + if(entry.second->isPythonExtension()) + delete entry.second; + } }; void ExtensionContainer::registerExtension(Base::Type extension, Extension* ext) { diff --git a/src/App/ExtensionContainerPyImp.cpp b/src/App/ExtensionContainerPyImp.cpp index 284a8a7361..1c800fe141 100644 --- a/src/App/ExtensionContainerPyImp.cpp +++ b/src/App/ExtensionContainerPyImp.cpp @@ -175,4 +175,4 @@ PyObject* ExtensionContainerPy::addExtension(PyObject *args) { } Py_Return; -} \ No newline at end of file +} diff --git a/src/App/GroupExtension.cpp b/src/App/GroupExtension.cpp index deb83361a4..7162a6d411 100644 --- a/src/App/GroupExtension.cpp +++ b/src/App/GroupExtension.cpp @@ -45,6 +45,7 @@ GroupExtension::GroupExtension() GroupExtension::~GroupExtension() { + Base::Console().Message("Delete group extension\n"); } DocumentObject* GroupExtension::addObject(const char* sType, const char* pObjectName)