So, I may have a rather unique use case, but I think it should work. But it does not work properly.
Basically, I have a class that uses the static factory (create) method, which returns shared_ptr for the newly created instance of the class. This class also has a virtual function that I would like to override from python and call from C ++.
Perhaps my code can express a thought more clearly than my words:
#include <string> #include <iostream> #include <boost/python.hpp> #include <boost/enable_shared_from_this.hpp> using namespace boost::python; using namespace boost; //~ Base Class ClassA class ClassA : public enable_shared_from_this<ClassA> { protected: ClassA(){} public: static shared_ptr<ClassA> create(){ return shared_ptr<ClassA>( new ClassA() ); } virtual void quack(){ std::cout<<"quacks like a ClassA Base"<<std::endl; } }; //~ Wrapper for ClassA struct WrapClassA : public ClassA, wrapper<WrapClassA> { static shared_ptr<WrapClassA> create(){ return shared_ptr<WrapClassA>( new WrapClassA() ); } void quack() { std::cout<<"quacking like a Wrapper..."<<std::endl; if (override f = this->get_override("quack")) { std::cout<<"... override found!"<<std::endl; f(); } else { std::cout<<"... no override found!"<<std::endl; ClassA::quack(); } } void default_quack(){ this->ClassA::quack(); } }; //~ C++ Call Test void quack( shared_ptr<ClassA> ptr ) { ptr->quack(); } //~ Exposing BOOST_PYTHON_MODULE(TestCase) { def( "quack", &quack ); class_<ClassA, shared_ptr<WrapClassA>, noncopyable>( "ClassA", no_init ) .def( "__init__", make_constructor(&WrapClassA::create) ) .def( "quack", &ClassA::quack, &WrapClassA::default_quack ) ; } //~ Main int main() { PyImport_AppendInittab( "TestCase", &initTestCase ); Py_Initialize(); boost::python::object main_module((boost::python::handle<>(boost::python::borrowed(PyImport_AddModule("__main__"))))); boost::python::object main_namespace = main_module.attr("__dict__"); boost::python::object testcase_module( (boost::python::handle<>(PyImport_ImportModule("TestCase"))) ); main_namespace["TestCase"] = testcase_module; FILE* test_file = fopen("test.py", "r"); PyRun_SimpleFile(test_file, "test.py"); fclose( test_file ); std::cin.get(); return 0; }
And here is the contents of test.py:
print "Testing.." class Derived( TestCase.ClassA ): def __init__( self ): TestCase.ClassA.__init__( self ) def quack( self ): print( "Quacks like a derived class!" ) Ainst = TestCase.ClassA() TestCase.quack( Ainst )
And the conclusion:
Testing ... wandering like a wrapper ...... no override found! tricks like Classic base quack like a wrapper ...... no redefinition found! tricks like ClassA Base
Thus, the base and class obtained in python act the same way. It seems that for some reason he did not find an override. I'm not sure, but this may have something to do with the create () function. Any ideas would be greatly appreciated!
EDIT:
Added pythonquack for py script - This works as expected:
def pythonquack( Inst ): print Inst Inst.quack()
The call to Ainst and Dinst says "Quacks like the Base" and "Quacks like the Derived", as you would expect. Therefore, for some reason, overrides do not return in C ++.