[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