[C++-sig] extending a c++ object by overriding it's virtual functions..

David Abrahams dave at boost-consulting.com
Tue Jun 27 19:42:46 CEST 2006


Kleistereimer <kleistereimer at gmx.de> writes:

> hi!
>
> i've a question about virtual functions and boost::python.
> i use it with a boost c++ extended python which is embeeded in c++.
>
> i have a virtual function that's going to be overridden in Python and
> called polymorphically from C++. (so i'm not wrapping c++ for use from
> python)

Huh?  It sounds like that's exactly what you're doing.

> for instance i want to allow users of my software to override the
> virtual void Login::OnLog(std::string) function using python.
>
>
> that's what 'wrapper' and 'get_override' is used for, right?

Right.

> if i would use it in python only, overriding works without these
> stuff too.
>
> so i duplicated the example at
> http://www.boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.virtual_functions_with_default_implementations
>
> and it works fine inside python as advertised:
>>>> base.f()
> 0
>>>> derived.f()
> 42
>
> but for this i wont need 'wrapper' and 'get_override'. This works for
> any boost c++ extension.
> now for the interesting stuff: (ak the problem)
>
> after running the script i do:
>
> 	Base *b = new BaseWrap;

BaseWrap is purely for the use of the Python class Called Base, which
is generated by class_<BaseWrap, ...>.  You shouldn't be using it
directly.

> 	int result = b->f();
> 	delete b;
>
> now i would expect the result to be 42, but i got 0.
> ====================================================

You have no right to expect anything in particular from that.  Of
course that doesn't build a Python derived object.  Just imagine you
had several Python classes derived from the Python class called Base.
Which one would it choose?

> so how to put 'wrapper' and 'get_override' to any use?

What you really seem to be asking is how do you construct an instance
of derived (a class defined in Python) from C++.  

> my sollution is to obtain the PyObject* of 'derived'
> and to force it manualy into m_ptr of 'wrapper' using
> 'detail::initialize_wrapper'

Stuff in detail namespaces is undocumented and not for user
consumption.  You shouldn't be using it directly.

> then 'get_override' worked as expected and i got 42.

 // substitute the module name where "derived" is defined for "__main__"
 python::object module = python::import("__main__");  
 python::object derived = module.attr("derived");
 python::object b = derived( /* arguments to __init__ here */ );
 int result = b.f();

The import function is not documented for 1.33.1 but you can see it at
http://boost-consulting.com/boost/libs/python/doc/v2/reference.html#embedding
(otherwise you have to use the Python 'C' API to do something
similar).

[Joel, any chance of getting
http://www.boost.org/libs/python/doc/tutorial/doc/html/python/embedding.html
updated with the facilities described in
http://boost-consulting.com/boost/libs/python/doc/v2/reference.html#embedding?]


HTH,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list