top header
com as a better c++term

 

home contents introduction com as a better C++ interfaces classes apartments labs lab setup quizzes
 
previousnext

 
Shortcomings

Some of these points are esoteric and could be ignored if you are full up!

Unloading unused DLLs - garbage collection

So far we have only written very simple clients. If our client was running 24 hours a day, 7 days a week, 52 weeks a year and creating and releasing thousands of object references, it would be very difficult for the client to keep track of which DLLs need to be loaded and which don't. While objects are automatically garbage collected on the release of the last interface pointer, there is no automatic garbage collection of DLLs with no more objects to service.

We could solve this by forcing the DLL to keep track of how many of its objects have extant references held by the client. A global DLL 'lock count' could be incremented when the first interface reference is passed to a client for a given object. The same lock count could decrement when an object deletes itself. The DLL would also have to export a function for the client to call periodically in order to establish whether the DLL could be unloaded. If the lock count is zero, the answer is yes, else it is no.

This allows the client to be in charge of the garbage collection strategy for objects and DLLs.

Unique interface ids

The Dynamic_cast() method and the out-of-band object creation function both suffer from the same problem - passing a string as an interface identifier. It is going to be difficult to guarantee that there will not be a clash of interfaces with common names. What we really need is a way to define interfaces uniquely within a certain scope.

Thread-safety

None of our code is thread-safe!

Using the registry as an implementation class repository

We need a way of uniquely identifying different implementations of IString to allow a client to choose the one they want. This unique class implementation identifier could be used as a key into a class repository, for instance the registry, which could contain the location details of the server. It is also possible to imagine every DLL providing standard exported functions for self-registration and de-registration of these details. This paves the way to a standard creation sequence for the client.

Location of objects

So far we have only looked at DLL-based objects, where the client and the object are in the same address space. The client has a direct reference to the object. Even this proved non-trivial when the client and object were implemented in the same language - a certain amount of standardization and programming discipline was required! While direct access to an object is fast, it may not be secure - there is no firewall between the client and the object.

An EXE-based object would live in a different address space from the client and the client and server may well have different security profiles. An EXE-based object could even be placed on a different machine, remote from the client.

Mismatch of context

Ideally, the programming model used by the client to access an object should be invariant to the location of the object. In fact, where possible, both caller and object should be unaware of impedance mismatch between them. Difference in location is just one example of context mismatch.

To facilitate this charade, a level of indirection is needed that can map between the runtime context the caller expects and the runtime context needed by the object. The caller must think that it is using the object in its own context. The object must think it is being called from its own context.

Imagine that it was possible to unambiguously define all characteristics of a class and its interfaces in some declarative description language. In this case it would be simple for the runtime to provide the right services for the class and automatically provide the "proxy" and "stub" code to map between the caller and the object when necessary. If such a description language allowed us to abstract away details specific to each host platform, such as calling conventions, a tool could be provided on each platform that spits out the right implementation language mappings for a given platform. Remember that on each different platform we are probably going to have to re-compile anyway.

Where are we?

Congratulations, you have just implemented what is essentially a COM component. It is missing some infrastructure glue and does not address any of the shortcomings discussed previously, but it is fundamentally a COM component.

If you have understood this, hopefully it will help to ease the path into developing and using COM components. You have already been exposed to many of the issues of COM development and have explored some of the common techniques used too.

Next we will look at how COM interfaces are implemented and used.


Top of document