[C++-sig] Re: wrapping interfaces and supplied implementations

David Abrahams dave at boost-consulting.com
Mon Apr 5 09:19:11 CEST 2004


[In response to http://article.gmane.org/gmane.comp.python.c++/5679/]

Hi Brian,

I know it's been "forever" since you posted this... sorry it took so long!

Brian Peters <topology at eircom.net> writes:

> Hello All,
>
> I'd like first to thank the Boost.Python team and commend them on their
> creation. Dave Abrahams et.al. have implemented code the likes of which
> I could not even have conceived, let alone writen. Boost MPL is not
> something I could ever have thought up. My hope is simply that someone
> some day finds my work as useful and impressive as I find theirs.

You're very welcome!  I'm very happy that the library helped you!

> I am trying to wrap a library that implements a generic programming
> approach to computational geometry and topology. To achieve this it
> defines a number of interfaces it requires to do its job. For developers
> who do not wish to code the details of these interfaces it also supplies
> concrete implementations.
>
> Having observed Dave Abrahams' penchant for a working test case I have
> developed a sandbox representing a portion of the library. 

When I got here I expected to see a you ask a question about how to
make the code work...  but I'm glad to see you got everything
to work on your own.

> It has three classes that are abstract base classes: IFacade,
> IManager, and IProduct. All their pure virtual methods are defined
> using raw pointers to abstract base classes.
>
> The idea is that an application asks the facade for a manager [
> IManager* IFacade::manager() ] and then uses the manager to create
> products [ IProduct* IManager::create(inti i) ]. The products have state
> that may be changed by the client or other operations of the facade. The
> manager can also store and retrieve products.
>
> A simple user can use the concrete Manager and Product classes supplied
> through these interfaces, but a more advanced user could derive their
> own product and manager from the abc's and pass that into the facade [
> void IFacade::setManager(IManager* manager) ]. The old addage applies:
> "The simple should be easy, but the complex should be possible." i.e use
> the supplied system if you want, but you can always over ride it with
> something more complex.

Nice!

> So now I want to be able to do the same thing in Python. I want to wrap
> everything so that a simple user can:
> * see the abstract base classes in python;
>    i.e. the interfaces, their doc strings, etc.
> * use the supplied implementation of manager and product
> * derive their own products and manager if they want/need to in python
>
> Well, I got it all working! Not only working, but doing cool python
> stuff too. Being new to python I have found it interesting that
> arbitrary attributes and methods can be added to any object regardless
> of its class.
>
> I think of a wrapped Product passed out to python from the supplied
> Manager class as a python envelope containing the C++ Product. I can
> scribble on that envelope. Spill coffee on it. Crumple it up a bit. I
> can store it in the manager and throw it away. When I later retrieve
> from the manager, not only is it the same C++ Product (i.e same
> address), but it is the same PyObject (i.e. same address, or "id" as
> they call it in the interpreter), AND it even has the same note
> scribbled on it and the coffee stain! Its like decorating C++ classes
> dynamically at run time.

That's the experience you're supposed to have ;^)

> I thought the article about C++/Python integration was cool when I read
> it a few months ago, but now I really see it. The line between Python
> and C++ is very fluid. (
> http://www.cuj.com/documents/s=8188/cuj0307abrahams )
>
> The code is attached below. For reference I am using the following
> (admittedly somewhat dated) environment:
> *  Python 2.2.2
> *  Boost 1.30.0
> *  Windows NT4 with MSVC6
> *  RH linux 2.4.2-2 with g++ 1.96
>
> I am offering this example to anyone that finds it useful. It is more
> complex than the examples I found in the documentation and code, yet
> still simple enough to examine in detail.
>
> I am hoping that those in the know will tell me if I have done anything
> terribly wrong. 

Well, I don't have time to give it a really in-depth review, but there
are a couple of issues that stick out:

1. The use of the undocumented component arg_from_python.  Wouldn't
   extract<> be more appropriate?  

2. You could make most of the handling of raw pointers use
   boost::shared_ptr instead.  Then you could probably get rid of all
   the uses of reference_existing_object, making the object ownership
   issues both cleaner and safer in general.

> I will gladly explain why I have done things the way I have and/or
> share the verbose version of this sandbox that contains a lot more
> testing functions and cout's. This message is already too long to do
> so here.

Well, you're right that it's long!  Actually, it has the tone and
flavor of a short magazine article.  CUJ was looking for more
Boost.Python articles not long ago; maybe you should develop your
example into one?  An article written from the perspective of someone
getting to know the library could help a lot of people get started
smoothly.

Cheers,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list