[C++-sig] Re: Auto-Generation and BPL v2
David Abrahams
dave at boost-consulting.com
Wed Nov 6 16:19:53 CET 2002
Brad King <brad.king at kitware.com> writes:
> Dave,
>
> I've finally gotten the time to work on python wrapper support in
> CABLE (http://public.kitware.com/Cable).
Wonderful! Let's have this discussion on the C++-sig, please...
> As I said before, I think generating BPL input is a good place to
> start. However, I have to consider the capabilities available to
> the user from python after wrapping.
Good idea.
> The wrapping tool will be used by ITK (www.itk.org), and that
> project has certain requirements.
>
> There are a couple problems I'd like to discuss with you.
>
> 1.) Namespaces v. Python Modules
>
> All code in ITK is in a C++ "itk" namespace. We'd like to have this
> namespace reflected in the python wrappers with code like this:
>
> # Load the ITK ptyhon wrappers.
> import itk
>
> # Create an instance of an ITK object.
> # Equivalent C++ code:
> # itk::Object::Pointer o = itk::Object::New()
> o = itk.Object.New()
What's the problem? Maybe it's the fact that we don't have static
function support in Boost.Python yet?
http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1420969
I understand why you want this, but for this /particular/ case I'd
suggest that an interface like
o = itk.Object()
would be more appropriate. Why expose to users that there's a factory
function at work here?
If you must have the static function interface, we just need to have a
discussion of the C++ interface questions I pose in the link above, so
that I can come up with a good design.
> 2.) Pointer Comparison
>
> While most of ITK uses built-in intrusive smart pointers (like the
> Object::Pointer in the above example), some methods return raw pointers.
> We need to be able to compare these pointers:
>
> p1 = o.GetFoo()
> p2 = o.GetFoo()
> p1 == p2
>
> The example at
>
> http://www.boost.org/libs/python/doc/v2/reference_existing_object.html
>
> demonstrates that this will not work.
Generally speaking, that's true.
> We could always write and wrap a function to compare the pointers
> for us, but that seems ugly. The CABLE Tcl wrappers keep track of
> all objects referenced by Tcl wrapper invokations. When a returned
> pointer/reference matches the type and value of a known object, the
> same pointer wrapper object is given back to Tcl, with an
> incremented reference count.
Aha. I've considered doing something like this in the past, but I
thought that tracking every object in this way *by default* would be a
price that not all users would be willing to pay. There are also
issues of base/derived class tracking (what happens if you're tracking
the base object and someone returns a pointer to the derived object,
which has a different address?) which make doing it right especially
difficult. Furthermore, when a Python object holds its C++ object by
smart pointer, there may not be any one single Python object
associated with a given C++ object (e.g. with shared_ptr), or the
associated Python object might change over time (e.g. with auto_ptr).
However, if itk's smart pointers are indeed intrusive, it seems to me
that you can just generate thin wrappers for your
raw-pointer-returning functions which generate the smart pointer for
you. In that case:
id(o.GetFoo()) != id(o.GetFoo())
But you can arrange for
o.GetFoo() == o.GetFoo()
by simply defining __cmp__ or __eq__ for whatever class that is.
Another approach we could consider is to arrange a way for you to say,
"pointers to any classes derived from X should be converted to python
this way". That requires an investment in some more Boost.Python work,
so it might have to wait a little while...
--
David Abrahams
dave at boost-consulting.com * http://www.boost-consulting.com
More information about the Cplusplus-sig
mailing list