Extending classes written in C++ using SWIG

Lars Moastuen tjordah at start.no
Fri Nov 26 10:24:04 CET 2004


Thx for your replies.

It seems I have created an example I thought were equal to my problem,
but it turned out that wasn't the case. I'm trying to figure out what
the difference is, but I find the classes quite similar to the example
below (too big to post here)... However, this problem can be solved by
using "directors" (http://www.swig.org/Doc1.3/Python.html#directors),
mine cannot...

Im currently testing if Boost.Python does the job better, but seems I
run into the same problem... I suspect it has something to do with STL
list or something, but I'm not sure yet...

Will post if I manage to create an example or if I find a solution.


"Phil Thompson" <phil at riverbankcomputing.co.uk> wrote in message news:<mailman.6788.1101400792.5135.python-list at python.org>...
> > tjordah at start.no (Lars Moastuen) writes:
> >
> >> class Bar
> >> {
> >> public:
> >> 	Bar() {};
> >> 	~Bar() {};
> >> 	virtual char* DoBar() const { return "Bar"; };
> >> };
> >>
> >> class Foo
> >> {
> >> public:
> >> 	Foo() {};
> >> 	~Foo() {};
> >> 	virtual void DoFoo(Bar* someBar) { cout << someBar->DoBar() << endl;
> >> };
> >> };
>  
> >> class ExtendedBar(Bar):
> >> 	def __init__(self):
> >> 		Bar.__init__(self);
> >>
> >> 	def DoBar(self):
> >> 		return "ExtendedBar";
> >>
> >> bar = ExtendedBar();
> >> foo = Foo();
> >> foo.DoFoo(bar);
>  
> >> I now expect to get "ExtendedBar" as output from UseFoo.py (since I've
> >> declared DoBar() as virtual, but I get "Bar"
>  
> >> Can anyone tell me why?
> >
> > Because "someBar->DoBar()" uses the vtable of the C++ dynamic type to
> > decide which actual DoBar method to call. Unfortunately there is no
> > C++ type corresponding to your ExtendedBar, there is no vtable for
> > your ExtendedBar type in C++. C++ only knows about C++ types; it is
> > unaware of the existence of Python types. Inside your Python instance
> > of ExtendedBar you are holding on to an instance of a C++ Bar.
> >
> >> Is there a way to remedy this??
> >
> > I don't know whether SWIG provides a boxed solution for this sort of
> > problem. One approach is to override the DoBar method in a subclass of
> > Bar in C++, and make that method pass the 'dispatch request' up into
> > Python. Then you expose the wrapper class in Python, rather than Bar
> > itself.
> >
> > It looks something like this:
> >
> > struct PseudoBar : public Bar {
> >         PyObject* self; // the Python instance wrapping this C++ instance
> >         void DoFoo () {
> >                 PyObject_CallMethod(this->self, "DoFoo", "");
> >         }
> > };
> >
> > Of course, you'll need to augment this with checks to ensure that
> > there really is something overriding the method, otherwise you'll end
> > up in an infinite loop ... but hopefully you get the idea. It's all a
> > bit tedious.
> 
> If SWIG really requires you to do this by hand (I'm surprised) then you
> might want to look at SIP (http://www.riverbankcomputing.co.uk/sip/). SIP
> generates code that does exactly what you suggest so that bindings behave
> as the OP was expecting.
> 
> Phil



More information about the Python-list mailing list