Having some problems with C++ inheritance and nb::rv_policy::reference_internal #1339
Replies: 2 comments 1 reply
|
@wjakob do you have any ideas/suggestions as to what I can do here? |
|
It looks like I did not test the code above. Also, note the C++ side has ownership, but it cannot destroy the object while Python is still using it. An alternative strategy would be to return a unique pointer or a shared pointer, depending on what you want regarding ownership. It seems you're the author of the C++ code, so another option would be to make |
Uh oh!
There was an error while loading. Please reload this page.
Hi,
I'm in the process of porting a fairly large project from boost::python to nanobind and I've hit something I can't figure out. I'm hoping someone here can help.
Before I start on the problem: the port is generally going pretty well. The nanobind docs are really helpful and the library itself is amazingly capable. I anticipated that this was going to be a giant slog, but I'm actually kind of enjoying it. Thanks!
I've distilled the problem I'm having as far as possible to create a reproducible. That's what I include here.
I have three C++ classes that I expose to Python: Atom, QueryAtom, and Mol. QueryAtom is derived from Atom. The Mol class stores a vector of (unique) pointers to Atoms. Here's the code snippet defining those (there's a link to the full file at the bottom of this question)
These are wrapped for nanobind like this:
And then I can use the classes like this and everything works as expected:
The problem comes when I define a new function that replaces an existing Atom with a QueryAtom and returns a pointer to the replacement as an Atom*.
Here's the C++ function:
I wrap this three different ways (this was part of trying to narrow down the problem):
The first of these, replace(), does what I am interested in: replaces the Atom (or QueryAtom) within the molecule with a QueryAtom and returns a pointer to the new QueryAtom as an Atom * using
reference_internal.When I call it, I get the following error:
The second function, replaceCopy(), which copies the new QueryAtom and returns it as an Atom * with
take_ownership, and returns the QueryAtom without problems.The second function, replaceLeaky(), which copies the new QueryAtom and returns it as an Atom * with
reference_internal(yes, I know this will leak... I'm just exploring the boundaries of when the return values work), generates the same exception:Here's sample python (builds on the sample code above) that demonstrates the problem:
Hopefully I'm doing something basic and stupid so this is easy to fix, but I haven't been able to resolve it.
Here's the whole demo cpp file to make reproducing easy:
foo1.cpp
Here's my test file:
foo.py
All reactions