[C++-sig] Re: Auto-Generation and BPL v2

Brad King brad.king at kitware.com
Wed Nov 6 19:46:38 CET 2002


Dave,

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

Oops, I didn't finish this section of the email.  I meant to point out
that I don't see a way to have nested namespaces treated as modules in
Python through BPL:

# itk::foo::Bar()
itk.foo.Bar()

Even if it were not possible to separately load this "itk.foo" module, it
would still be nice from a naming perspective.

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

I agree that this particular case is prettier when hiding the New()
method, but there is also something to be said for a one-to-one
correspondence among C++, Tcl, and Python implementations of the same
program.

Also, CABLE is intended to be a tool separate from ITK, and should not
have ITK-specific hacks in it.  Then, in order to achieve this syntactic
change there would have to be a way of specifying it in the configuration
file.  One of my design goals for CABLE was to produce wrappers that
reflect the original C++ as closely as possible, and with as few
configuration options as possible.

This actually brings up the other main issue with automatic generation.
Whenever a return_value_policy is required, CABLE will have to make some
assumptions, and probably just always use reference_existing_object.
Anything different would require per-method configuration, which already
starts to defeat the purpose of auto-generation of wrappers.

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

I'd definately prefer the def(..., static_()) approach over having
static_def.  Here is another approach that crossed my mind:

struct A { static void StaticMethod(); };

class_<A>("A", init<>())
  .def("StaticMethod", static_(&A::StaticMethod));

I'm not sure I'd prefer this over

class_<A>("A", init<>())
  .def("StaticMethod", &A::StaticMethod, static_());

but I thought I'd mention it anyway.

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

In Tcl the tracking is more necessary because the wrapper objects each
have a corresponding Tcl command used to invoke methods on that object.
CABLE needs to keep track of all the commands it creates and destroys to
keep this working.  The tracking isn't as necessary for Python, though, so
you're right that the extra cost may not be worth it.

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

I went through the same thought process for CABLE's Tcl wrappers.  At the
time I decided to go for the pointer comparison and ignore the problems to
get something working.  I have yet to thoroughly revisit the issue.
However, I've toyed with the idea of automatic down-casting of pointers to
polymorphic C++ types.

> 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.
[snip]
> 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...

These options are definately worth my consideration, but this decision
will depend somewhat on the configurability decision I mentioned above.

-Brad





More information about the Cplusplus-sig mailing list