[C++-sig] Fwd: Passing Python-derived class back into a native C++ class doesn't match the C++ signature

Adam Preble adam.preble at gmail.com
Sat Nov 12 17:34:49 CET 2011


I am seeing this come up in many variations, with people doing slightly
different things.  I haven't yet seen an example doing something in this
exact progression.  I apologize here because I feel like I'm repeating a
topic that has come up on the list before--even just a few weeks back.
Here's what I'm trying to do:

1. Expose a base class with a pure virtual method.
2. Expose an acceptor class that accepts that base class as an argument for
a method.
3. Implement the base class in Python
4. Pass that implemented class to the acceptor

I am using Boost 1.42.

I have some source snippets.  I am using the wrapper method, though without
it I had the same result:

    class BaseTest
    {
    public:
        virtual int GimmeNumber() = 0;
        virtual ~BaseTest() {}
    };

    class BaseTestWrap : public BaseTest, public wrapper<BaseTest>
    {
        int GimmeNumber()
        {
            return this->get_override("GimmeNumber")();
        }
    };

    class ITakeFoo
    {
    public:
        void DoStuff(BaseTest* test)
        {
            cout << "Whoo calling BaseTest to do stuff: " <<
test->GimmeNumber() << endl;
        }
    };

...

    class_<BaseTestWrap, boost::noncopyable>("BaseTest")
        .def("GimmeNumber", pure_virtual(&BaseTest::GimmeNumber))   // I
have tried &BaseTestWrap here too.  Not sure what to do but it doesn't
solve the issue at hand
        ;

    class_<ITakeFoo>("ITakeFoo", init<>())
        .def("DoStuff", &ITakeFoo::DoStuff)
        ;


In Python:
class DerivedTest(BaseTest):
    def __init__(self):
        pass

    def GimmeNumber(self):
        return 100

dt = DerivedTest()
ITF = ITakeFoo()
ITF.DoStuff(dt)

The DoStuff() call fails:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    ITakeFoo.DoStuff(ITakeFoo, DerivedTest)
did not match C++ signature:
    DoStuff(ITakeFoo {lvalue}, BaseTest*)

I can appreciate there being a memory-management-related policy issue but I
can't see what might have to be done.  What else am I missing?  I guess I
should add the documentation I've found would be nice to go this last mile
and show how to do this step in the Boost documentation.  The wrapper stuff
was fine enough but they don't see it getting called back into the native
C++ code.

As it stands, if I do type.mro(DerivedTest), I see:
[<class '__main__.DerivedTest'>, <class 'BaseTest'>, <type
'Boost.Python.instance'>, <type 'object'>]

It appears to some extent it got it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20111112/9491b590/attachment.html>


More information about the Cplusplus-sig mailing list