<br>There's been some progress, using the boost object implementation.<br>However it appears that the "chg" method of the DerivedO object is not<br>overridden properly. So when it is changed in python, I get what I<br>
expect, but when it is changed in C++, it appears to run the Base::chg<br>method instead of the DerivedO::chg method. I'm sure I'm only missing<br>some tiny detail now.<br><br>---- mymodule.cpp ------------------------------------------------<br>
<br>#define MYTYPE object<br>#define MYDEFAULT object(0)<br><br>/*<br><br>#define MYTYPE string<br>#define MYDEFAULT ""<br><br>*/<br><br><br>#include <iostream><br>#include <fstream><br>#include <string><br>
using namespace std;<br><br>#include <boost/python.hpp><br>using namespace boost::python;<br><br>struct Base <br>{<br> Base() { s = MYDEFAULT ; }<br> Base(MYTYPE input){ s = input; }<br> virtual ~Base() {}<br> virtual MYTYPE run() { return s; }<br>
virtual void chg(MYTYPE input) { s = input; }<br>private:<br> MYTYPE s;<br>};<br><br>struct BaseWrap : Base, wrapper<Base><br>{<br> BaseWrap() : Base() {}<br> BaseWrap(MYTYPE input) : Base(input) {}<br><br> MYTYPE run() {<br>
if (override run = this->get_override("run"))<br> return run();<br> return Base::run();<br> }<br><br> MYTYPE default_run() {<br> return this->Base::run();<br> }<br><br> void chg(MYTYPE input) {<br>
if (override chg = this->get_override("chg"))<br> chg(input);<br> Base::chg(input);<br> }<br><br> void default_chg(MYTYPE input) {<br> this->Base::chg(input);<br> }<br>};<br><br>typedef boost::shared_ptr<Base> BasePtr;<br>
<br>BasePtr g(new Base);<br><br>BasePtr get_g() {<br> return g;<br>}<br><br>BasePtr set_g(BasePtr input_g) {<br> BasePtr tmp;<br> tmp = g;<br> g = input_g;<br> return tmp;<br>}<br><br>MYTYPE run_g() {<br> MYTYPE tmp;<br>
tmp = g->run();<br> return tmp;<br>}<br><br>void chg_g(MYTYPE input) {<br> g->chg(input);<br>}<br><br>BOOST_PYTHON_MODULE(mymodule) {<br> <br> def("set_g", set_g);<br> def("get_g", get_g);<br>
def("run_g", run_g);<br> def("chg_g", chg_g);<br><br> class_<BaseWrap, boost::noncopyable>("Base", init<>()) <br> .def(init<MYTYPE>())<br> .def("run", &Base::run, &BaseWrap::default_run)<br>
.def("chg", &Base::chg, &BaseWrap::default_chg)<br> ;<br><br> register_ptr_to_python< BasePtr >();<br><br>}<br><br>---- test.py ------------------------------------------------<br><br>#!/usr/bin/env python<br>
<br>from mymodule import *<br> <br>class DerivedS( Base ):<br> def run( self ):<br> x = Base.run( self )<br> return x+x<br><br>class DerivedO( Base ):<br> def chg( self, val ):<br> y = [1,<br>
1.0,<br> 'string',<br> ['array'],<br> ('tuple',)<br> ][val]<br> Base.chg( self, y )<br> def run( self ):<br> x = Base.run( self )<br>
return x+x # defined for all 5 types above.<br><br>---- test run ------------------------------------------------<br><br>>>> from mymodule import *<br>>>> b1 = Base()<br>>>> b1.run()<br>
0<br>>>> x = b1.run()<br>>>> set_g(b1)<br><mymodule.Base object at 0x4020d3ac><br>>>> run_g()<br>0<br>>>> b2 = Base('init_str')<br>>>> ib1 = set_g(b2)<br>>>> ib1.run()<br>
0<br>>>> b2.run()<br>'init_str'<br>>>> run_g()<br>'init_str'<br>>>> chg_g(40)<br>>>> b2.run()<br>40<br>>>> run_g()<br>40<br>>>> ds = DerivedS('derived')<br>
>>> ib2=set_g(ds)<br>>>> ib2.run()<br>40<br>>>> ds.run()<br>'derivedderived'<br>>>> run_g()<br>'derivedderived'<br>>>> ds.chg('changed in python ')<br>>>> ds.run()<br>
'changed in python changed in python '<br>>>> chg_g('changed in C++ ')<br>>>> run_g()<br>'changed in C++ changed in C++ '<br>>>> ds.run()<br>'changed in C++ changed in C++ '<br>
>>> class DerivedO( Base ):<br>... def chg( self, val ):<br>... y = [1,<br>... 1.0,<br>... 'string',<br>... ['array'],<br>... ('tuple',)<br>
... ][val]<br>... Base.chg( self, y )<br>... def run( self ):<br>... x = Base.run( self )<br>... return x+x # defined for all 5 types above.<br>...<br>>>> do = DerivedO()<br>
>>> do.run()<br>0<br>>>> ids = set_g(do)<br>>>> ids.run()<br>'changed in C++ changed in C++ '<br>>>> do.chg(1)<br>>>> do.run()<br>2.0<br>>>> do.chg(2)<br>>>> do.run()<br>
'stringstring'<br>>>> do.chg(3)<br>>>> do.run()<br>['array', 'array']<br>>>> run_g()<br>['array', 'array']<br>>>> do.chg(4)<br>>>> run_g()<br>
('tuple', 'tuple')<br>>>> chg_g(2)<br>>>> do.run()<br>4<br>>>> chg_g(1)<br>>>> do.run()<br>2<br>>>> chg_g('this is ')<br>Traceback (most recent call last):<br>
File "<stdin>", line 1, in <module><br> File "<stdin>", line 8, in chg<br>TypeError: list indices must be integers<br>>>> chg_g(3)<br>>>> run_g()<br>6<br>>>> do.chg(1)<br>
>>> do.run()<br>2.0<br>>>> do.chg(2)<br>>>> do.run()<br>'stringstring'<br>>>> do.chg(3)<br>>>> do.run()<br>['array', 'array']<br>>>> do.chg(4)<br>
>>> do.run()<br>('tuple', 'tuple')<br>>>> do.chg(0)<br>>>> do.run()<br>2<br>>>> run_g()<br>2<br>>>> chg_g(0)<br>>>> run_g()<br>0<br>>>> chg_g(1)<br>
>>> run_g()<br>2<br>>>> chg_g(2)<br>>>> run_g()<br>4<br>>>> do.run()<br>4<br>>>> do.chg(2)<br>>>> do.run()<br>'stringstring'<br>>>> run_g()<br>'stringstring'<br>
>>> chg_g(2)<br>>>> do.run()<br>4<br>>>> run_g()<br>4<br>>>> <br>