@@ -7,6 +7,57 @@ using namespace ngla;
7
7
#include < myadt.hpp>
8
8
9
9
10
+ // Workaround to ensure same lifetime for C++ and Python objects
11
+ // see https://github.com/pybind/pybind11/issues/1546
12
+ namespace pybind11 ::detail {
13
+
14
+ template <>
15
+ struct type_caster <std::shared_ptr<BaseMatrix>>
16
+ {
17
+ PYBIND11_TYPE_CASTER (std::shared_ptr<BaseMatrix>, _(" BaseMatrix" ));
18
+
19
+ using BaseCaster = copyable_holder_caster<BaseMatrix, std::shared_ptr<BaseMatrix>>;
20
+
21
+ bool load (pybind11::handle src, bool b)
22
+ {
23
+ BaseCaster bc;
24
+ bool success = bc.load (src, b);
25
+ if (!success)
26
+ {
27
+ return false ;
28
+ }
29
+
30
+ auto py_obj = py::reinterpret_borrow<py::object> (src);
31
+ auto base_ptr = static_cast <std::shared_ptr<BaseMatrix>> (bc);
32
+
33
+ // Construct a shared_ptr to the py::object
34
+ auto py_obj_ptr = std::shared_ptr<object>{
35
+ new object{py_obj},
36
+ [](auto py_object_ptr) {
37
+ // It's possible that when the shared_ptr dies we won't have the
38
+ // gil (if the last holder is in a non-Python thread), so we
39
+ // make sure to acquire it in the deleter.
40
+ gil_scoped_acquire gil;
41
+ delete py_object_ptr;
42
+ }
43
+ };
44
+
45
+ value = std::shared_ptr<BaseMatrix> (py_obj_ptr, base_ptr.get ());
46
+ return true ;
47
+ }
48
+
49
+ static handle cast (std::shared_ptr<BaseMatrix> base,
50
+ return_value_policy rvp,
51
+ handle h)
52
+ {
53
+ return BaseCaster::cast (base, rvp, h);
54
+ }
55
+ };
56
+
57
+ template <>
58
+ struct is_holder_type <BaseMatrix, std::shared_ptr<BaseMatrix>> : std::true_type {};
59
+ }
60
+
10
61
template <typename T>
11
62
void ExportSparseMatrix (py::module m)
12
63
{
@@ -570,7 +621,7 @@ void NGS_DLL_HEADER ExportNgla(py::module &m) {
570
621
new (instance) BaseMatrixTrampoline(); }
571
622
)
572
623
*/
573
- .def (py::init<> ([]() { return new BaseMatrixTrampoline (); } ))
624
+ .def (py::init<> ())
574
625
.def (" __str__" , [](BaseMatrix &self) { return ToString<BaseMatrix>(self); } )
575
626
.def_property_readonly (" height" , [] ( BaseMatrix & self)
576
627
{ return self.Height (); }, " Height of the matrix" )
0 commit comments