I have an example C++ base class (Song) with a virtual method (chorus) returning void that is called by another method (play) of the same class. I want to be able to derive a python class from this and override the virtual method. I experience the following behavior:
1. If I simply instantiate the wrapped base class in python and call play, **the virtual chorus is never entered/executed**. 2. If I create a derived class and override the virtual chorus, the derived chorus is executed correctly. 3. If I change the base class chorus to return int (or anything) instead of void, the base class chorus is executed correctly. I have wrapped my class as described here: http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/wrapper.html My example C++, python code, and output python output is below (I've tried to make it as concise as possible). I can work around this issue in my application by having my virtual method return an unused object, although this is not ideal. I would appreciate any other suggestions, whether I'm doing something incorrectly, or is this possibly a boost python bug? //------------------------------------------------ // Has virtual method returning void // Numbers indicate order in which the print statements should appear. //------------------------------------------------ class Song { public: virtual ~Song(){} void play() { std::cout << "\n1) Base class --> Song.play" << std::endl; chorus(); std::cout << "3) Base class <-- Song.play" << std::endl; } // THIS METHOD IS NEVER EXECUTED virtual void chorus() { std::cout << "2) Base class Song.chorus returning void" << std::endl; } }; struct SongWrapper : Song, bp::wrapper<Song> { void chorus() { if (bp::override chorus = this->get_override("chorus")) chorus(); return; Song::chorus(); return; } void default_chorus() { this->Song::chorus(); } }; //------------------------------------------------ // Has virtual method returning int // Numbers indicate order in which the print statements should appear. //------------------------------------------------ class AnotherSong { public: virtual ~AnotherSong(){} void play() { std::cout << "\n1) Base class --> AnotherSong.play" << std::endl; chorus(); std::cout << "3) Base class <--AnotherSong.play" << std::endl; } // THIS METHOD (returning int) IS EXECUTED virtual int chorus() { std::cout << "2) Base class AnotherSong.chorus returning int" << std::endl; return 0; } }; struct AnotherSongWrapper : AnotherSong, bp::wrapper<AnotherSong> { int chorus() { if (bp::override chorus = this->get_override("chorus")) return chorus(); return AnotherSong::chorus(); } int default_chorus() { return this->AnotherSong::chorus(); } }; BOOST_PYTHON_MODULE(Songs) { bp::class_<SongWrapper,boost::noncopyable>("Song") .def("play", &Song::play) .def("chorus", &Song::chorus, &SongWrapper::default_chorus) ; bp::class_<AnotherSongWrapper,boost::noncopyable>("AnotherSong") .def("play", &AnotherSong::play) .def("chorus", &AnotherSong::chorus, &AnotherSongWrapper::default_chorus) ; } #------------------------------------------------ # Python file ... #------------------------------------------------ from Songs import Song, AnotherSong # Base class chorus returning void is not executed: step 2 is missing in the output s1 = Song() s1.play() # Derived class chorus is executed: step 2 in the output class Chart(Song): def chorus(self): print "** 2) Derived class Chart.chorus" c1 = Chart() c1.play() # Base class chorus returning int is executed: step 2 in output s2 = AnotherSong() s2.play() #------------------------------------------------ # Python output ... # In first case, step 2 is missing ... chorus was not executed #------------------------------------------------ 1) Base class --> Song.play 3) Base class <-- Song.play 1) Base class --> Song.play ** 2) Derived class Chart.chorus 3) Base class <-- Song.play 1) Base class --> AnotherSong.play 2) Base class AnotherSong.chorus returning int 3) Base class <--AnotherSong.play ________________________________ This email is intended solely for the recipient. It may contain privileged, proprietary or confidential information or material. If you are not the intended recipient, please delete this email and any attachments and notify the sender of the error.
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig