Merge pull request #91 from Holt59/fix-ifiletree-sharedptr

Fix deletion of shared_ptr created from C++.
This commit is contained in:
Mikaël Capelle
2021-03-02 19:27:32 +01:00
committed by GitHub
3 changed files with 34 additions and 3 deletions
+4 -1
View File
@@ -9,6 +9,7 @@
#include <isavegame.h>
#include <isavegameinfowidget.h>
#include "shared_ptr_converter.h"
#include "ifiletree.h"
#include "pythonwrapperutilities.h"
@@ -108,7 +109,9 @@ ModDataChecker::CheckReturn ModDataCheckerWrapper::dataLooksValid(std::shared_pt
}
std::shared_ptr<MOBase::IFileTree> ModDataCheckerWrapper::fix(std::shared_ptr<MOBase::IFileTree> fileTree) const {
return basicWrapperFunctionImplementationWithDefault<std::shared_ptr<MOBase::IFileTree>>(this, [](auto&&... args) { return nullptr; }, "fix", fileTree);
return utils::clean_shared_ptr(
basicWrapperFunctionImplementationWithDefault<std::shared_ptr<MOBase::IFileTree>>(
this, [](auto&&... args) { return nullptr; }, "fix", fileTree));
}
/// end ModDataChecker Wrapper
+6 -2
View File
@@ -4,6 +4,7 @@
#include <QUrl>
#include <QWidget>
#include "shared_ptr_converter.h"
#include "pythonwrapperutilities.h"
#include "uibasewrappers.h"
@@ -330,10 +331,10 @@ IPluginInstaller::EInstallResult IPluginInstallerSimpleWrapper::install(
using return_type = std::variant<
IPluginInstaller::EInstallResult,
std::shared_ptr<IFileTree>,
std::tuple<IPluginInstaller::EInstallResult, std::shared_ptr<IFileTree>, QString, int>> ;
std::tuple<IPluginInstaller::EInstallResult, std::shared_ptr<IFileTree>, QString, int>>;
auto ret = basicWrapperFunctionImplementation<return_type>(this, "install", boost::ref(modName), tree, version, nexusID);
return std::visit([&](auto const& t) {
auto result = std::visit([&](auto const& t) {
using type = std::decay_t<decltype(t)>;
if constexpr (std::is_same_v<type, IPluginInstaller::EInstallResult>) {
return t;
@@ -349,6 +350,9 @@ IPluginInstaller::EInstallResult IPluginInstallerSimpleWrapper::install(
return std::get<0>(t);
}
}, ret);
tree = utils::clean_shared_ptr(tree);
return result;
}
/// end IPluginInstallerSimple Wrapper
+24
View File
@@ -96,6 +96,30 @@ namespace utils {
}
};
// release the bpy::object associated with the deleter of the given shared_ptr,
// if the given shared_ptr has a Boost.Python deleter
//
// this should only be used when returning from Python objects that have been created
// on the C++ side, e.g. if IFileTree.createOrphanTree() from Python and then return
// the tree
//
// for reason yet to be known, Boost.Python had a custom deleter in this case that tries
// to delete the bpy::object and fails, so we have to release the object manually
//
template <class SharedPtr>
SharedPtr clean_shared_ptr(SharedPtr&& ptr) {
if (auto* d = get_deleter<boost::python::converter::shared_ptr_deleter>(ptr); d != nullptr) {
// we cannot do a proper reset() here, even with the GIL lock, for unknown reason,
// so we only release
//
// this might create lost references to Python object but this should not happen
// too often so hopefully it's not a big issue
//
d->owner.release();
}
return ptr;
}
}
#endif