Boost logo

Boost :

From: Jesse Jones (jesjones_at_[hidden])
Date: 2001-07-20 17:52:01


At 3:10 PM +0200 7/18/01, Martin Reinecke wrote:
>Hello,
>
>I'd like to find out if there is any interest to include the
>DLC library for dynamically loadable classes into Boost.
>This library allows loading and unloading of different implementations
>for abstract classes at runtime in an easy and type-safe way.

I'd like to see a higher level set of classes that provide support
for reusable components. Something along the lines of COM, but
perhaps a bit more powerful and better integrated with C++. I've been
using a component library that's an extended version of what Adobe
uses in InDesign. It's similar to COM, but uses exceptions instead of
return codes, strings instead of GUIDs, automated reference counting
(via smart pointers), and is a bit more dynamic.

Interfaces are aggregated into higher level objects called "bosses".
The boss layout is currently defined using XML files. For example:

    <Boss name = "Application" singleton = "true">
       <Inherit name = "Base Drag and Drop App"/>
       <Interface name = "IDropAppHelper" impl = "CDropAppHelper"/>
    </Boss>

To instantiate an object you use the boss's name. Normally the object
will be deleted when all of it's references go away, but you can mark
bosses as being singletons so that they are only instantiated once
and aren't deleted until the app exits. The boss I listed above
derives from an abstract boss which provides a set of default
interfaces and implementations and defines one custom implementation.

To get at an interface on the boss you write code like this:

    IApplicationPtr app(L"Application");
    app->Init();

    IDropAppPtr drop(L"Application");
    drop->Start(new CMyFileFilter);

   app->Run();

This gets two interfaces on the same boss, initializes them (we have
to use two-phase initialization because the implementation objects
are created via factory methods), and enters the main event loop. You
could also have written the third line like this:

    IDropAppPtr drop(app);

This does a query on the boss containing the app interface for the
IDropApp interface. If it's not found drop is set to NULL.

The IDropAppHelper interface is defined in the UI framework. In
abridged form it looks like this:

    class IDropAppHelper : public XUnknown {

    public:
       virtual void Startup(const std::vector<XFileSystemSpec>& specs) = 0;
    };

    typedef XInterfacePtr<IDropAppHelper> IDropAppHelperPtr;
    typedef XInterfacePtr<const IDropAppHelper> IConstDropAppHelperPtr;

The implementation is a custom one:

    class CDropAppHelper : public IDropAppHelper {

    public:
       virtual ~CDropAppHelper();

         CDropAppHelper(XBoss* boss);

    public:
       virtual void Startup(const std::vector<XFileSystemSpec>& specs);
    };

    DEFINE_INTERFACE_FACTORY(CDropAppHelper)

    CDropAppHelper::~CDropAppHelper()
    {
    }

    CDropAppHelper::CDropAppHelper(XBoss* boss)
    {
       IDropAppHelper::DoSetBoss(boss);
    }

    void CDropAppHelper::Startup(const std::vector<XFileSystemSpec>& specs)
    {
       // do stuff with the files here
    }

This is the core of it although there are some features I haven't
discussed like interface aggregation and dynamic addition/removal of
interfaces. It's a very different style than traditional C++
programming, but it works really well with complex objects like UI
widgets, with an app that you want to make modular (especially if you
want to allow third party modules like InDesign), or if you want to
craft reusable components.

   -- Jesse


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk