I have a C++ class that would like to expose to Python. (Assuming this class has already been written and couldn't be easily modified). In this class, there is a member which is a pointer, and I would like to expose that member as well. Here is a minimal version of the code.
struct C {
C(const char* _a) { a = new std::string(_a); }
~C() { delete a; }
std::string *a;
};
BOOST_PYTHON_MODULE(text_detection)
{
class_<C>("C", init<const char*>())
.def_readonly("a", &C::a);
}
It compiles okay, except that there is a Python runtime error when I tried to access that field:
>>> c = C("hello")
>>> c.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*
which is understandable. But the question is that is it possible to expose member pointer a
through Boost Python at all? And how?
Instead of using def_readonly
, use add_property
with a custom getter. You'll need to wrap the getter in make_function
, and since the getter is returning a const&
you must also specify a return_value_policy
.
std::string const& get_a(C const& c)
{
return *(c.a);
}
BOOST_PYTHON_MODULE(text_detection)
{
using namespace boost::python;
class_<C>("C", init<const char*>())
.add_property("a", make_function(get_a, return_value_policy<copy_const_reference>()))
;
}