[C++-sig] Re: register_ptr_to_python and get_pointer
David Abrahams
dave at boost-consulting.com
Wed Dec 24 14:23:54 CET 2003
Marc Kwiatkowski <Marc.Kwiatkowski at veritas.com> writes:
> Yet another question/observation about register_ptr_to_python.
>
> Given a function that returns a ref-ptr, it seems that all that is
> really necessary is to provide a get_pointer template function for it
> and then invoke the register_to_python function.
That's right.
> None of the wrapper stuff is necessary.
What "wrapper stuff"? Do you mean A_wrapper in the example in the
docs?
> For example:
>
> class X {
> public:
> X(wstring const& aValue) : value(aValue) {}
> wstring value;
> };
>
> my_ref_ptr<X> NewX(wstring const& aValue )
> { return my_ref_ptr<X>(new X(aValue)); }
>
> namespace boost { namespace python {
>
> template <class T> T* get_pointer(my_ref_ptr<T> const& p) {
> return p.get();
> }
> }}
>
> BOOST_PYTHON_MODULE(test) {
>
> class_<X>("X", init<wstring const&>())
> .def_readwrite("value", &X::value);
>
> def("NewX", &NewX);
>
> register_ptr_to_python< my_ref_ptr< X > >();
> }
>
> That's all there is too it. This seems so much more straight forward
> than the sample described in
> libs/python/doc/v2/register_ptr_to_python.html
It illustrates something different from your code.
> On the other hand, when I used ref-ptrs with a mix of derived and base
> classes, I can find no permutation of wrapper and smart pointer that
> will work to get at a base method from a derived object ptr that is
> downcast to a base object pointer.
That's an upcast.
> For example, given the Base, Derived, and Factory classes attached
> below, the following script fails
>
>>>> from pytest import Base, Factory, Derived;f=Factory()
>>>> d=f.NewDerived("i am derived")
>>>> d.GetString()
> u'i am derived'
>>>> b=f.Downcast(d)
>>>> b.GetString()
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> Boost.Python.ArgumentError: Python argument types in
> Derived.GetString(Derived)
> did not match C++ signature:
> GetString(class Filer::Test::Example::PyDerivedWrapper {lvalue})
> GetString(class Filer::Test::Example::PyDerived {lvalue})
Well, you didn't include enough information to make this problem
reproducible (a definition of my_ref_ptr is missing, and I don't know
what else), so there's only so much I can do to help.
>From this part of the error message
Derived.GetString(Derived)
it's clear that b is actually a Python Derived object, not a Base
object as one would expect (try doing print type(b)). It seems like
there's something very wrong here, and the only explanation I can
come up with is that my_ref_ptr<Base>::element_type is Derived. See
http://www.boost-consulting.com/boost/libs/python/doc/v2/pointee.html.
The other thing that looks suspicious is that you haven't declared an
inheritance relationship between Base and Derived using bases<...>.
There'd be no need to expose GetString again in Derived if you did
that.
HTH,
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list