C++ to python with boost.python: Exposing virtual bool operator()(int)=0

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pedro

    #1

    C++ to python with boost.python: Exposing virtual bool operator()(int)=0

    Hello pythonians! ;-D ,

    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; }
    ...
    [color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]
    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()) ; }
    ...
    [color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]
    44
    3
    is 20<23 and 24<23 True False
    64
    68[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]


Working...