[C++-sig] Re: Python and debug STLport (was: Re: nocygwin toolset)

David Abrahams david.abrahams at rcn.com
Mon May 13 16:58:56 CEST 2002


----- Original Message -----
From: "Raoul Gough" <RaoulGough at yahoo.co.uk>

...continued from an earlier jamboost posting...

> > > There is one remaining problem with python, but it only occurs in the
> > debug
> > > build. The module is question is
libs\python\example\simple_vector.cpp.
> > > Could it be something to do with vector iterator not being a pointer?
> > It's
> > > being compiled with STLport's debug STL via -D_STLP_DEBUG and
produces:
> > >
> > > d:/boost/CVS/boost/boost/python/caller.hpp: In function `static
struct
> > > PyObject * boost::python::caller<unsigned
> > > int>::call<_STL::__vector<double,_STL::allocator<double> > >(size_t
> > > (_STL::__vector<double,_STL::allocator<double> >::*)() const,
PyObject
> *,
> > > PyObject *)':
> > > d:/boost/CVS/boost/boost/python/detail/functions.hpp:73:
instantiated
> > from
> > > `boost::python::detail::wrapped_function_pointer<unsigned
int,unsigned
> > int
> > > (_STL::__vector<double,_STL:
> > > :allocator<double> >::*)() const>::do_call(PyObject *, PyObject *)
> const'
> > > f:/stlport/STLport-4.5.3/stlport/stl/debug/_iterator.h:153:
> > instantiated
> > > from hered:/boost/CVS/boost/boost/python/caller.hpp:232: no matching
> > > function for call to `from_python (PyObject *&,
> > > boost::python::type<_STL::__vector<double,_STL::allocator<double> >
&>)'
> >
> > I don't think so. Not sure what the problem is there.
>
> I think I've tracked this problem down. Here's an example which
demonstrates
> the limitation that is causing the problem with the STLport debug STL:
>
> -------------------
>
> #include <boost/python/class_builder.hpp>
> namespace python = boost::python;
>
> struct base
> {
>   int foo () const { return 0; }
> };
>
> struct derived : public base { };
>
> BOOST_PYTHON_MODULE_INIT(simple_vector)
> {
>   python::module_builder this_module("simple_vector");
>   python::class_builder<derived> builder (this_module, "derived");
>
>   builder.def (&derived::foo, "foo");   // Boom
> }
>
> --------------
>
> The type of &derived::foo is pointer to *base* member function - ummm, I
> guess you'd write this int (base::*)() const. Anyway, the compiler seems
to
> barf on this because class_builder was instantiated with derived, and it
> won't deal with a call to the base class member function (even with
public
> derivation). I don't understand enough about boost::python to say why
this
> should be.

Yep, I actually fixed this problem for Boost.Python v2. Doing it for all
the compilers I'm supporting proved to be really awful. See
boost/python/class.hpp and boost/python/detail/member_function_cast.hpp.
However, there are limitations to this approach: for one thing it means
that whenever a member function is being wrapped, the target class has to
be available. I sort of gave on this when it came to the new-style Python
iterator support I'm about to check in for v2, mostly because it would
complicate things too much.

> Now, the really unfortunate thing about this is that, when _STLP_DEBUG is
> defined, the STLport vector (_STL::vector) is actually derived from the
> otherwise non-existant _STL::__vector (these are the real identifiers
after
> macro expansions). This base class defines all the handy member
functions,
> so their types don't match the class builder which is, of course,
> instantiated with _STL::vector.

Yeah, I'm familiar with how that works, having written parts of it ;-)

> Close attention to the original error message actually does identify the
> problem: the "no matching function" error indicates that the actual type
> involves __vector and the long list of candidate functions has entries
> only for vector without the underscores. There seems to be an inherent
> incompatability between boost::python and at least some of the STLport
> containers in debug mode.

Naah, users can't portably take the address of standard library member
functions, in part so implementors can do things like this. However, you
can /non-portably/ do it with a cast to the appropriate target function
type (member function pointers implicitly convert down the inheritance
hierachy, so the cast is legal).

-Dave







More information about the Cplusplus-sig mailing list