SWIG and Callbacks

Jim jbublitzNO at SPAMnwinternet.com
Wed Jun 19 14:42:50 EDT 2002


David Abrahams wrote:
> "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


>>>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.

%Import <module name> links you to all of the code from another
module (and it's antecedents).

>>>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?

If you want to support that many filesets - I'm on the 8th PyKDE
version (KDE2.1.1 -> KDE3.0.1) in 14 months (all still supported),
amd I'll probably do one or two more releases in the next 6 months.
Any of the versions can build against one of 3 or more different Qt
versions (Qt2.3.0 -> Qt2.3.2, or Qt3.0.0 -> Qt3.0.4). It adds up.

>>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.

I believe they're called "Python users" :) (j/k)

>>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.

I think we mean the same thing. I've done thin wrappers for a
spreadsheet plugin, and basically re-architected the entire API
for Python, including things like changing the grid addressing
from numeric row and col to more typical alphanumeric
(eg (2, 6) -> "B6"). Full bindings would compile to several MB;
binding just the wrapper took about 100K plus about the same for
the wrapper. Most of the methods in the wrapper were 5 lines or less.

sip code:

      void f (int, char * = expression1, Foo const& = expression2) [1]
      void f1 (int, char *);
      void f2 (int);

[1] Might depend on what the expressions are - I've done constants
and function/method calls as defaults, but not arbitrary expressions,
so I'm not sure. It might take more than a line. OTOH, a real
wrapper could throw out the defaults for 'f' (in Python) and replace
them with f1, f2, etc.



>>>>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 certainly depends on the code you're generating bindings for,
your knowledge of C++, maintability requirements, lots of other
factors.

> 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 a lot of C++ compilers too, most of which are
incompatible to some extent (certainly at the binary
level). Choice is good.

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

Project wide code comparisons might be useful, but that's more
work than I'd want to do.

>>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?

Basically a parser/code generator to create input files for
sip is easier than the equivalent for Boost.Python, since for
sip input files, I don't need to know anything about a class
member except whether it's an enum, method or variable. Stuff
like 'virtual', 'static', 'const', pure virtuals or default
values is just syntactic noise - it just gets passed on to sip,
which already knows how to deal with that stuff.

Also, I can generate versioned code by comparing the code
generated for a new h file with the previous version's sip
(input) file - the same parser does both since the syntax
is nearly identical. The version state transition logic is
tricky and that's where I have problems automatically
generating input files at the moment. Just generating a
sip input file is pretty simple to automate and seems to
work well.

OTOH, Boost.Python seems to care more about whether methods
are virtual or handling default values, and the 'input' files
for Boost.Python are cpp files and the syntax is method calls
instead of declarations - all that makes a parser harder to
write IMO. There might be a different way to approach it that's
easier - some intermediate file for example, or a variation
on diff.

The tradeoff is that it would be easier to automatically
generate code for templates with Boost.Python than with
a sip input file generator and in fact I just flag that
stuff and write it manually the first time - it gets
recycled on subsequent versions. The parser/input file
generator/version generator in general seems to be easier
with sip. It's probably not a concern for most people.


Jim




More information about the Python-list mailing list