[C++-sig] Boost::Python: overriding and smart pointers
Sybren A. Stüvel
sybren at stuvel.eu
Wed May 23 16:21:42 CEST 2012
Dear list,
I'm trying to get my head around shared pointers combined with overloaded
methods. I want to create instances of my class both in Python and C++, but
for some reason I can't get both to work with the same code. I've
constructed a minimal example to show you what I'm trying to do. The full
C++ code with syntax highlighting can be found at
http://pastebin.com/ZqG79QUL
Sorry for the long mail, but I saw no other way to show my issues in a
clear and unambiguous way.
--------------------------------------
class ExampleObject {
public:
std::string name;
ExampleObject(const std::string & name) : name(name) {}
virtual ~ExampleObject() {}
virtual int some_number() { return 12; }
};
typedef boost::shared_ptr<ExampleObject> ExampleObjectPtr;
ExampleObjectPtr create_example_object(const std::string & name) {
return boost::make_shared<ExampleObject>(name);
}
void print_name(ExampleObjectPtr object) {
std::cout << "Example object named '" << object->name
<< "', nr = " << object->some_number()
<< std::endl;
}
--------------------------------------
These are the class and functions that I want to wrap. The
ExampleObject::some_number method should be overridable in Python. To this
end, I've created the following wrapper class:
--------------------------------------
struct ExampleObject_wrapper : ExampleObject, wrapper<ExampleObject> {
ExampleObject_wrapper(const std::string & name)
: ExampleObject(name), wrapper<ExampleObject>()
{}
virtual int some_number(void) override {
if( override func_override = this->get_override("some_number"))
return func_override();
return default_some_number();
}
int default_some_number(void) {
return this->ExampleObject::some_number();
}
};
typedef boost::shared_ptr<ExampleObject_wrapper> ExampleObject_wrapper_ptr;
--------------------------------------
The Python module is declared as follows:
--------------------------------------
BOOST_PYTHON_MODULE(wraptest) {
def("create_example_object", &create_example_object);
def("print_name", &print_name);
class_<ExampleObject_wrapper, boost::noncopyable, ExampleObjectPtr>
("ExampleObject", init<const std::string &>())
.def("some_number", &ExampleObject_wrapper::some_number,
&ExampleObject_wrapper::default_some_number)
;
}
--------------------------------------
This is the Python code that I'm testing with:
--------------------------------------
from wraptest import *
class ExampleSubclass(ExampleObject):
def some_number(self):
return ExampleObject.some_number(self) * 2
# Test from Python
from_py_obj = ExampleSubclass('from python')
print_name(from_py_obj)
# Test from C++
from_cpp = create_example_object('from C++')
print_name(from_cpp)
--------------------------------------
When I compile the module (VS2010, Python 3.2.2, Boost 1.48) and run the
Python script, I would expect the object created in C++ to show the number
12, and the object created in Python to show the number 24. However, the
output is this:
Example object named 'from python', nr = 12
Example object named 'from C++', nr = 12
Running a debugger also shows that the ExampleObject_wrapper methods aren't
called at all. When I edit the class_<...> line by replacing
ExampleObjectPtr with ExampleObject_wrapper_ptr, the from-Python object
works just fine, but the from-C++ object gives me an exception:
Example object named 'from python', nr = 24
Traceback (most recent call last):
File "C:\workspace\rage\scripts\test_wrapping.py", line 13, in <module>
from_cpp = create_example_object('from C++')
TypeError: No to_python (by-value) converter found for C++ type: class
boost::shared_ptr<class ExampleObject>
What should I do to be able to instantiate objects in C++ and Python alike?
Kind regards,
--
Sybren A. Stüvel
http://stuvel.eu/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20120523/4f03f995/attachment.html>
More information about the Cplusplus-sig
mailing list