How can I pass derived Python instances to C++?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How can I pass derived Python instances to C++?

James Amundson-2
I would like to be able to create a Python class derived from a C++
class, then pass a instance of the Python class back to C++. It isn't
clear to me if there is an easy way to do this.

Here is a simple example of what I wish worked, but doesn't:

C++ side:

#include <boost/python.hpp>
#include <iostream>
class Foo
{
public:
     Foo(){};
     virtual void
     doit(){std::cout << "doing it Foo style\n";};
};
void
foodoer(Foo & foo)
{
     foo.doit();
}
using namespace boost::python;
BOOST_PYTHON_MODULE(foo)
{
     class_<Foo >("Foo", init<>())
             .def("doit", &Foo::doit);
     def("foodoer", foodoer);
}

Python side:

import foo
class Bar(foo.Foo):
     def __init__(self):
         pass
     def doit(self):
         print "doing it bar style"

f = foo.Foo()
# next line works
foo.foodoer(f)

b = Bar()
# next line does not work
foo.foodoer(b)


Does anyone have any advice for me?

Thanks,
Jim Amundson

_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: How can I pass derived Python instances to C++?

Stefan Seefeld-2
On 2011-09-08 13:01, James Amundson wrote:
> I would like to be able to create a Python class derived from a C++
> class, then pass a instance of the Python class back to C++. It isn't
> clear to me if there is an easy way to do this.
>
>

> import foo
> class Bar(foo.Foo):
>     def __init__(self):
>         pass

You need to call the base class constructor explicitly in Python. That
should do the trick.

    Stefan

--

      ...ich hab' noch einen Koffer in Berlin...

_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: How can I pass derived Python instances to C++?

James Amundson-2
On 09/08/2011 12:17 PM, Stefan Seefeld wrote:

> On 2011-09-08 13:01, James Amundson wrote:
>> I would like to be able to create a Python class derived from a C++
>> class, then pass a instance of the Python class back to C++. It isn't
>> clear to me if there is an easy way to do this.
>>
>>
>> import foo
>> class Bar(foo.Foo):
>>      def __init__(self):
>>          pass
> You need to call the base class constructor explicitly in Python. That
> should do the trick.
Yes. Of course. Thanks! That should have been obvious to me.

In case anyone else is reading, I'll answer my own next question and say
that Stefan's advice is necessary but not sufficient. In order to get my
example to work, I had to read up on overridable virtual functions in
Boost Python, e.g. here:
     http://wiki.python.org/moin/boost.python/OverridableVirtualFunctions

Here is my working example:

C++:

#include <boost/python.hpp>
#include <iostream>
class Foo
{
public:
     Foo()
     {
     }
     ;
     virtual void
     doit()
     {
         std::cout << "doing it Foo style\n";
     }
     ;
};
void
foodoer(Foo & foo)
{
     foo.doit();
}

using namespace boost::python;

struct Foo_callback : Foo
{
     Foo_callback(PyObject *p) :
         Foo(), self(p)
     {
     }
     Foo_callback(PyObject *p, const Foo& foo) :
         Foo(foo), self(p)
     {
     }
     void
     doit()
     {
         return call_method<void > (self, "doit");
     }
     static void
     default_doit(Foo& self_)
     {
         self_.Foo::doit();
     }
private:
     PyObject* self;
};

BOOST_PYTHON_MODULE(foo)
{
     class_<Foo, Foo_callback >("Foo", init<>())
     .def("doit", &Foo_callback::default_doit);
     def("foodoer", foodoer);
}

Python:

import foo
class Bar(foo.Foo):
     def __init__(self):
         foo.Foo.__init__(self)
     def doit(self):
         print "doing it Bar style"

f = foo.Foo()
foo.foodoer(f)

b = Bar()
foo.foodoer(b)


--Jim
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig