0

I have python embedded in my application and I want to send a python function a raw pointer to an object I have in my C++ code.
The only way I found how to do this is to wrap the pointer with an auto_ptr or a shared_ptr but I prefer not to do that since I don't want the python code to have any chance of holding a reference to the object in my code.

Is this possible with boost::python?

3
  • Looks like stackoverflow.com/a/5056462/138772 has your solution. "Pass the object pointer via boost::python::ptr to python. This will prevent the python interpreter from making a copy". Commented Jun 26, 2012 at 18:50
  • @JAB Nice! Write it as an answer and I'll accept it. Commented Jun 27, 2012 at 7:24
  • Actually, it seems I didn't look into it enough/didn't read what I copied and pasted properly. It looks like using boost::python::ptr will actually make the possibility of dangling references more likely, as according to boost.org/doc/libs/1_49_0/libs/python/doc/v2/ptr.html, "Normally, when passing pointers to Python callbacks, the pointee is copied to ensure that the Python object never holds a dangling reference." Commented Jun 27, 2012 at 14:54

1 Answer 1

0

If you have raw pointer to some C++ object mapped into Python then you can make another Python object around original pointer using adapter in such way:

template<typename PtrT>
struct PtrAdapter {
    auto& get(PtrT ptr)  { return *ptr; }
};

Then make it's Python mapped type and allow implicit conversion:

class_<Cluster<LinksT>*, noncopyable>(typpedName<LinksT>("ClusterPtr", true, true)
, "Raw hierarchy cluster pointer\n")
    .def("__call__", &PtrAdapter<Cluster<LinksT>*>::get,
        return_internal_reference<>(),
        "referenced cluster")
    ;
register_ptr_to_python<Cluster<LinksT>*>();

Note that referenced type (in this case Cluster<LinksT>) also must be mapped to the appropriate Python object.
Then for such C++ code:

Cluster<LinksT>* cl = clusters.head();
process(cl);
Id cid = cl->id();

You can use similar Python code:

cl = clusters.head()
process(cl)
cid = cl.id()

But if you don't need some special processing of pointer to C++ object then it's obviously better to use boost::python::ptr.
Also you should consider alternatives mentioned here: boost::python: howto call a function that expects a pointer?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.