views:

223

answers:

3

Hi everybody.

I have an extensible product that allows 3rd party developers to write plugins for it. The aspects that can be extended are documented and interfaces are provided in the SDK. Currently, I'm using COM and I'm getting pretty comfortable with it. I especially like the ability to provide interface versioning in a unified manner. I consider it to be a requirement because you never know what you're gonna need in the future.

Just to be precise, here's an example. Let's suppose I have an interface representing a particular feature:

class IFeature
{
public:
  virtual void DoFeatureTask() = 0;
};

Then after the interface is already documented (and someone may have used it in the plugin code) I'm realizing, I need more from this feature. Maybe, there is an option I need to provide. I just define the second version:

class IFeature2
{
public:
  virtual void DoFeatureTask(int theOption) = 0;
};

I don't mean I intend to have lots of versions. But it just may happen. In COM, because every interface is associated with a GUID, I can query a preferred implementation, determine its presence, and, finally, fall back to a legacy one.

But after glancing through C++/COM-related questions, I noticed many recommendations against COM. So maybe it's not the best choice and I'm just too old-school. Can you advise on an alternative?

+1  A: 

COM is a good architecture for plug-ins. Sure everybody complains about it, but they would complain about anything that could replace it in pretty much the same terms. The complexity is inherent in the problems that is solves and the OS primitives it has available to solve them. (OK, some of the complexity is a historical relic)

COM has a rich set of tools for describing interfaces, it plays nicely with .NET code and C++ code. There really isn't anything else that can match it's breadth of plugability.

Microsoft uses it for their multimedia playback architecture, where there are literally hundreds of different teams that never communicate with each other in any way, and yet still manage to contribute components that work together to play back audio and video. That all by itself is proof of the viability of COM in an extensible architecture.

The main problem I have with COM personally is threading and apartments. A given thread can only have one apartment type, and it's essentially impossible to write a well-behaved GUI application that doesn't have a main thread that is STA. Couple this with the fact that a window's message pump has to be the thread that created it, and it becomes quite hard to design a COM based plug-in architecture that allows for multiple threads to call a single plugin.

For example, you can't create an interface on an STA thread and then hand it to another thread to be used, and then wait for that thread. If the thread that created the interface isn't running a pump, you deadlock.

If you went with a non-COM architecture, you could allow multi-threaded plugins or spinning up threads in order to call into plugins more easily. But you would also have to solve a whole collection of problems that COM solves for you.

Now, if you were prepared to ditch support for unmanaged interoperability, you could go with a .NET based architecture, but if you wanted to interoperate between that architecture and C or C++, the way to do that would be .... COM!

John Knoeller
A: 

Using COM for an SDK this way is not so bad per se. It gives your customers language independence. So either side could be using Visual C++, GCC, .net, delphi or whatnot. This could be important to you, I don't know. COM is quite easy to consume from .net, so if you have to support both .net as well as other languages, COM is great.

The second advantage of COM is the versioning of interfaces, which will enable binary components written for 1.0 to work with your 2.0 out of the box. That means your framework will have to conform to your new and your old contracts. If you promise that, all customers will agree that's fantastic. But it could very well be that nobody uses this feature, and you get away with renumbering all the interfaces for a major release.

If you go for COM, make sure to test your API's from .net based languages, because not all COM parameter types can be marshalled to and from .net.

jdv
A: 

COMs advantage, is also its disadvantage: A few versions down the line and you have version ed interfaces everywhere the code starts to look very crufty.

And, while adding interfaces is easy, the very dynamic plugin nature of the bindings means its very VERY hard to make a complete audit of consumers of a set of version ed interfaces to try and remove support for unused or obsolete implementations.

As much as interfaces are meant to be immutable - sometimes it turns out that an interface was badly designed in v1, and being unable to delete it means you might not be able to refactor the application fully.

Chris Becke
But what's the alternative?
Kerido
alternative? The alternative to COM is to re-invent it again. But badly.
Chris Becke
Is there a non-microsoft framework out there that is farily well supported and/or widely used? ie: something cross-platform?
JPDecker
XPCOM is a cross platform version of COM. The basic underlying principal of COM - as it applies to C++ - is a pretty solid plugin architecture - use pure virtual classes to define implementation contracts.As bad as the problems with COM can be - interfaces are a very powerful plugin mechanism.
Chris Becke