SWIG and Callbacks

David Abrahams david.abrahams at rcn.com
Tue Jun 18 18:36:29 EDT 2002


"Jim" <jbublitzNO at SPAMnwinternet.com> wrote in message
news:3D0F807A.40203 at SPAMnwinternet.com...
> David Abrahams wrote:
> > "Jim" <jbublitzNO at SPAMnwinternet.com> wrote in message
>
> >>Template-based code does require special treatment with sip.
> >>In most cases where I've wrapped template-based types or
> >>classes, I manually write C++ code for conversion C++ <-> Py
> >>(sip has some functions that make that easier) and implement
> >>it as a sip 'mapped type', which lets me refer to the same
> >>conversion code from any return value or arg.
>
> > That's a given with Boost.Python; with v2 conversions are automatically
> > registered in a global repository so they can be re-used automatically
> > across extension modules.
>
> For C++ code with a lot of templates Boost.Python has an
> advantage, particularly if you're early on the learning curve.

Well, yes, but I wasn't talking about that. I was talking about re-usability
of conversions. My point was that if you wrap a class X in one module, you
can can wrap [member] functions that operate on X in another module.

> Sure - you can extend sip in almost any way you want also
> (the bindings generated are C++ code), but it may be a
> little trickier fitting things in the binding's framework.
> It's also possible to embed custom Python or C++ code in
> sip description files and I do that when appropriate (rarely).
> It kind of goes against the design philosophy of sip IMHO,
> so I try to avoid it personally.

Understood.

> >>The real problem wouldn't seem to be C++ types as such, but
> >>finding a useful (to the Python programmer) representation
> >>via PyObject, and still maintaining the range of abilities
> >>built into the C++ code (esp things like subclassing).
>
> > That's built-in to Boost.Python. V1 had to implement a complicated
Python
> > class look-alike itself; V2 uses Python's new-style classes so
subclassing
> > "just works". Making virtual functions overridable in Python requires a
> > small amount of boilerplate on the part of the programmer. I often wish
I
> > had a good C++ parser front-end which I could use to automate that part.
>
> New-style classes lock you into Python 2.2+ though - I've
> got users still at 1.5.2 and place a lot of emphasis on long
> term version support.

That didn't seem to be important to my users. The amount of code I was able
to throw away when I started using new-style classes was really staggering
(and gratifying!). If it was really important to some people, it should be
possible to re-implement all of the Python 2.2+ features used by
Boost.Python very much more cleanly in C++, for 1.5.2 compatibility... but
it's not a job I want to spend time on. As they say, there will be many more
people using future versions than have every used any existing version.
Anyway, those who really need it can always get v1 out of its archive and
dust it off.

> sip does the virtual code boilerplate'
> automatically, unless the method requires handwritten code
> for some other reason (rare). On the stuff I do, I see a lot
> more virtual code than templates, but that obviously varies
> a lot.

Yeah, that's important. Another area that Boost.Python could use some help
from a parser with is in wrapping overloaded functions and those with
default args. C++ is missing the ability to represent an overload set as a
single object ;-)

> > OK. The C++ code you're wrapping still has to get by with #ifdef, I
> > suppose...
>
> Depends on the code I suppose. Qt and KDE just issue all
> new files - no versioning in the C++ code.

Ah. I guess if they were wrapped with Boost.Python, the wrapping code would
be treated the same, then?

> > There is no "resorting to C++" with Boost.Python -- Boost.Python
*embraces*
> > C++! Since you're coding the wrappers in C++ anyway, it's trivial to
make a
> > "thin wrapper function" which calls the function being wrapped if you
want
> > to change the interface somehow. Then you just wrap the thin wrapper.
>
> I finally went back to your website - I took your 'like an
> IDL' comments a little too literally. IMHO, the fact that
> Boost.Python *is* C++ is a big advantage for people who
> want/need that. Personally, I don't want to write C++,
> which is how I got into this in the first place.

<smile> A lot of people seem to feel that way.

> Thin wrappers are easily implementable with sip too. In
> contrast to the very large packages like PyQt and PyKDE,
> they tend to be very lightweight and quick to build.

Sorry, I think you misunderstood what I meant by "thin wrapper". A classic
trivial example might be used to wrap a function with default args:

    // function to wrap
    void f(int a, char* b = expression-1, Foo const& c = expression-2);

Thin wrappers:

    void f1(int a, char* b) { f(a,b); }
    void f2(int a) { f(a); }

wrapping code:

    module("my_module")
        .def("f", f)
        .def("f", f1) // overloads handle
        .def("f", f2) // default args
    ;

Obviously you can do arbitrary pre- and post- processing inside a thin
wrapper function.

> >>Yes, but I don't write it - I just edit it mostly to correct
> >>mistakes my description file generator creates and to handwrite
> >>code where the generator has flagged that. Crude but effective (TM)
> >>Even without automation, the process is easiest if you start by
> >>saving the h file with a .sip extension and then (mostly) delete
> >>the things that sip doesn't want/need, so it's still mostly
> >>editing (sometimes A LOT of editing).
>
> > That seems to be the key difference. It's not clear wether it's really
an
> > advantage, but I suppose that time will tell.
>
> I doubt that it's ever clearly an advantage.

Really? It seems like it should lower the barrier to entry and get people
started with an iterative development process, at least.

> It works very
> well for PyQt and PyKDE because of the C++ style those projects
> use generally - very consistent,

That uniformity tends to be important to parser-based systems. I learned a
lot about the wide range of code people needed to wrap during v1
development, and I'm trying hard to lift restrictions imposed by that kind
of assumption for v2.

> relatively small amount of
> template usage, lots of enums and of course sip has features to
> support Qt. sip has been used outside of the Qt/KDE area, but
> perhaps not on anything available publicly yet.

Probably the docs are the main obstacle there. It's amazing how many
different wrapping tools there seems to be a market for; people will try
anything once <wink>!

> There's certainly plenty of opportunities for something like
> "benchmarketing".

Let's not, please!

> Either one of us could contrive examples to
> make one or the other look clearly better, but like most things
> it's probably more rational to look at what the user actually
> needs to accomplish. I've avoided actual code comparisons,
> because the simple cases tend to be one-sided one way or the
> other.

Well, code comparisons are important in showing the system's user-interface.

> >>I should probably go back and review Boost. I had thought that
> >>with Boost it was possible to wrap as much or as little of a
> >>C++ library as you want to.
>
> > That's true.
>
> Big selling point IMHO.

:-)

> >>I had the impression SWIG was supposed to do most of that in a single
>  >>step. Just wondering if I could implement something like that with
> Boost,
>  >>or need to code a line manually for each method/class/whatever.
>
> > If you have something which can mostly parse your headers, you can
generate
> > much of the wrapping code automatically.
>
> Yes - it looks like that should be possible. Virtual code
> might require a little more work in generating Boost.Python
> code automatically, but the tradeoff is probably less things
> flagged as requiring handwritten code.

Not sure what you mean here about the tradeoff. Example?

> > Yep. BTW, Boost is much more than just my Python binding library, so
please,
> > for the sake of the other authors: "Boost.Python" when discussing my
lib.
>
> Noted - I've tried to do better in this post.

Thanks.

> > Not sure that you'll find much to steal; they're so different in
approach...
>
> I can be very creative when stealing other people's code :)
>
> Actually "under the hood" sip and Boost.Python have similarities.

Yeah, well that page is slightly outdated, and doesn't really show much of
what's going on other than the class data structure. There really aren't
many other practical ways to make extension class wrappers.

-Dave





More information about the Python-list mailing list