[C++-sig] Re: wrapping interfaces and supplied implementations
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/]
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.
> 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
More information about the Cplusplus-sig