[C++-sig] Share C++ Object Extended in Python?

David Brownell groups at DavidBrownell.com
Tue Jun 19 09:04:43 CEST 2007


I have an existing C++ definition that resembles the code below, and would 
like to extend the Events interface using Python.  However, I get errors 
in Python when I attempt to create a Python object that is shared between 
Python and C++.

    struct Events
    {
        virtual void Foo(char const *tcString) = 0;
    };

    struct Object 
    {
        void Init(Events &events) { _pEvents = &events; }
        void DoFoo() { _pEvents->Foo("Fire foo!"); }
    
        Events * _pEvents;
    };

When using the following boost python code generated with Py++ things work 
well in some cases, but not all.
struct Events_wrapper : Events, bp::wrapper< Events > {

    Events_wrapper()
        : Events()
          , bp::wrapper< Events >(){
          // null constructor
         }

        virtual void Foo( char const * tcString ){
            bp::override func_Foo = this->get_override( "Foo" );
            func_Foo( tcString );
        }
    };

    BOOST_PYTHON_MODULE(tester){
        bp::class_< Events_wrapper, boost::noncopyable >( "Events" )    
            .def( 
                "Foo"
                , bp::pure_virtual( &::Events::Foo )
                , ( bp::arg("tcString") ) );

        bp::class_< Object >( "Object" )    
            .def( 
                "DoFoo"
                , &::Object::DoFoo )    
            .def( 
                "Init"
                , &::Object::Init
                , ( bp::arg("events") ) );
    }

This following Python code works fine:

    import tester
    class Events(tester.Events):
	def Foo(self s): 
		print s
    e = Events()
    o = tester.Object()
    o.Init(e)
    o.DoFoo()

But I get the error...
    
    Traceback (most recent call last):
      File "<interactive input>", line 1, in ?
    ArgumentError: Python argument types in
      Object.Init(Object, Events)
    did not match C++ signature:
      Init(struct Object {lvalue}, struct Events {lvalue} events)

...with the code:

    import tester
    class Events(tester.Events):
	def __init__(self):
		self.i = 0
	def Foo(self s): 
		print s
    e = Events()
    o = tester.Object()
    o.Init(e)
    o.DoFoo()

It appears that I am not doing something right with the binding code, but 
so far I haven't been able to find the right combination of boost::python 
argument decorators to get the job done.  It seems like I could use an auto_ptr 
if I wanted Object to take ownership of the event object, but I want both 
the Python and C++ code to continue to modify the same instance of Event. 
 Is there some way I can do this?

Thanks for your help!
David Brownell 







More information about the Cplusplus-sig mailing list