Extending classes written in C++ using SWIG
Lars Moastuen
tjordah at start.no
Fri Nov 26 04:24:04 EST 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