2

I have a class in C++.
I create an object from this class in my C++ code. I want this object to be accessible in Python. I use boost::shared_ptr to keep the object address.

I've checked out some posts about this but wasn't very helpful. I think the best way is to make an object in Python namespace after interpreter initialization and then assign my boost shared_ptr to the created object in Python.

I've wrapped my class using BOOST_PYTHON_MODULE in cpp and tested some ways like namespace["my_module_name_in_python"] = class<"my_class">... to be able to create an object in python and fill it with the shared_ptr.

In summery my question is how's possible to pass a C++ object contained in a shared_ptr to python.

Thanks in advance

5
  • Have you seen that: wiki.python.org/moin/boost.python/SimpleExample ? Commented Sep 18, 2013 at 14:00
  • @elmo: This does not seem relevant to the question. Commented Sep 18, 2013 at 14:04
  • Can you dereference the object and pass it by value? Can you pass a weak pointer instead? Do you need python to keep a refcount? Commented Sep 18, 2013 at 14:15
  • @Constantinius: it is or I don't understand question. From what I understand question boils down to "how do I expose C++ class to/share object with Python?". And that is all documentation on that wiki. As for handling pointers there is wiki.python.org/moin/boost.python/PointersAndSmartPointers As for "weird" construction there is make_constructor: wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor Commented Sep 18, 2013 at 14:36
  • If possible, could you please provide an sscce? As it stands, I am having problems understanding the actual problem needing to be solved. Commented Sep 18, 2013 at 19:21

1 Answer 1

1

This is taken from the official boost python documentation.

Lets say you have a C++ class that looks like this:

class Vec2 {
public:
    Vec2(double, double);
    double length();
    double angle();
};

You can derive the Python interface for it like that:

object py_vec2 = class_<Vec2>("Vec2", init<double, double>())
    .def_readonly("length", &Point::length)
    .def_readonly("angle", &Point::angle)
)

The class definition is now stored in the variable py_vec2. Now I can create an instance of said class with:

object vec_instance = py_vec2(3.0, 4.0);

This instance can now be injected to a Python interpreter. E.g set it into a variable of the "__main__" module:

object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");

main_namespace["vec_instance"] = vec_instance;
Sign up to request clarification or add additional context in comments.

1 Comment

Cool! I've tried this though I have a problem with this method too. My class contains different types which forces me to define them too. When you define all these in a BOOST_PYTHON_MODULE(<module_name>) everything is fine but with the above mentioned method I don't know how nested objects should be defined. I hope it's been clear.

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.