I have a little problem when I expose (assisted by boost.python) classes
with virtual functions, specially with operator().
In the C++ code below I test two different implementations of a member
function of A that
takes as an argument the abstract class Base (see Option 1 / Option 2):
- Both compile without problems
- Only the second works in python (see python program below).
It seems like if the problem is in the way I expose operator()... but I
do not understand it very well
Any clue about why this is happening?I would appreciate any comment on this.
Thank you very much in advance. :-D
Pedro.
//............... ............... ............... ..........
//............... . C++ code........... ...........
//............... ............... ............... ..........
#include <boost/python.hpp>
#define OPTION1
//#undef OPTION1
struct Base
{
virtual ~Base() {}
virtual int f() = 0; // Like in
Boost.python tutorial
virtual int g(int) = 0; // With 1 argument
virtual bool operator()(int ii) =0; // __call__ - type function
};
class A{
private:
int v_;
public: A(int v): v_(v){}
#ifdef OPTION1
/* Option 1 */ int fun(Base& c) const { return
c(v_)?(c.g(v_)+ c.f()):33; }
#else
/* Option 2 */ int fun(Base& c) const { return (c.g(v_)+c.f()) ; }
#endif
};
//::::::::::::::: ::::::::::::BOO ST::PYTHON in
action::::::::: ::::::::::::::: :::
using namespace boost::python;
struct BaseWrap : Base, wrapper<Base>
{
int f(){return call<int>(this->get_override(" f").ptr());}
int g(int ii){return call<int>(this->get_override(" g").ptr(),ii );}
bool operator()(int ii){ return
call<bool>(this->get_override(" operator()").pt r(),ii);}
};
BOOST_PYTHON_MO DULE(test2py)
{
class_<A>("A",i nit<int>())
.def("fun",&A:: fun);
class_<BaseWrap , boost::noncopya ble>("Base")
.def("f", pure_virtual(&B ase::f))
.def("g", pure_virtual(&B ase::g))
.def("__call__" , pure_virtual(&B ase::operator() )) ;
};
//............... ............... ............... ..........
//............... . Python code........... ........
//............... ............... ............... ..........
from test2py import *
## Extension of C++ class in python
class Derived(Base):
def f(self):
return 44
def g(self,n):
return n
def __call__(self, v):
return (v<23)
d=Derived()
print d.f()
print d.g(3)
print "is 20<23 and 24<23", d(20), d(24)
a=A(20)
print a.fun(d)
b=A(24)
print b.fun(d)
//............... ............... ............... ............... ..........
//............... . Executing Python code........... .......
//............... ............... ............... ............... .........
With Option 1 IS NOT WORKING!!
...
int fun(Base& c) const { return c(v_)?(c.g(v_)+ c.f()):33; }
...
44
3
is 20<23 and 24<23 True False
Traceback (most recent call last):
File "d:\My_Document s\src\pysource\ test.py", line 29, in ?
print a.fun(d)
TypeError: 'NoneType' object is not callable
With Option 2 IS WORKING!!
...
int fun(Base& c) const { return (c.g(v_)+c.f()) ; }
...
44
3
is 20<23 and 24<23 True False
64
68