[C++-sig] return_internal_reference & overriding methods in a class.

Roman Yakovenko roman.yakovenko at gmail.com
Thu Jun 25 06:41:29 CEST 2009


On Thu, Jun 25, 2009 at 6:31 AM, Nicolas Lara<nicolaslara at gmail.com> wrote:
> Hello,
>
> I'm having trouble trying to override a method on a class exposed to
> Python. I cannot modify the original class, so I need to wrap it to
> change the behaviour of some methods to be Python compatible. The
> classes look like the following:
>
> struct DocumentWrap : Document, wrapper<Document>
> {
>  DocumentWrap() : Document(){ };
>  DocumentWrap(const Document&) { };
>  wstring toString()
>  {
>    wstring w(_T("test"));
>    return w;
>  }
>  int test(){
>    return 1;
>  }
> };
>
>  class_<Hits>("Hits", init<int>())
>    .def("doc", &Hits::doc, return_internal_reference<>());
>  class_<DocumentWrap>("Document")
>    .def("toString", &DocumentWrap::toString)
>    .def("test", &DocumentWrap::test)
>    ;
>
> Hits::doc returns a Document. If I do:
>
>>>> d = Document()
>>>> d.test()
> 1
>>>> d.toString()
> "test"
>
> I get the right answer. However, If I obtain the class through Hits I
> get a reference to a c++ object of type Document (not DocumentWrap) so
> trying to execute the methods yield:
>
> Traceback (most recent call last):
>  File "t.py", line 10, in <module>
>    d.test()
> Boost.Python.ArgumentError: Python argument types in
>    Document.test(Document)
> did not match C++ signature:
>    test(DocumentWrap {lvalue})
>
> Traceback (most recent call last):
>  File "t.py", line 10, in <module>
>    d.toString()
> Boost.Python.ArgumentError: Python argument types in
>    Document.toString(Document)
> did not match C++ signature:
>    toString(DocumentWrap {lvalue})
>
> Is there any way to get python to understand the internal reference to
> Document can be treated as a DocumentWrap?

I don't think so. What you ask doesn't make sense.

The better solution would be to replace problematic function in another way:

struct Doc{

xyz** do_smth();

};

add new global function:

boost::python::list do_smth4py( Doc& d){
    ///call your function
}

and register it instead of the original function

class_< Doc>(...)
    .def( "do_smth", &::do_smth4py )


The Python user will not note the difference.

HTH

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/


More information about the Cplusplus-sig mailing list