) is an extremely flexible substrate for building distributed object systems or components. These components can be built in any language that supports the COM standard for layout of binary objects and callable from any language that either has this layout or supports the late binding interface IDispatch.
- A binary standard for layout of objects. This layout is simply a vtable which is generated by using C++ abstract base classes (equivalent to Java interfaces). They have to be laid out the same way as Microsoft's C++ compiler does them, but that's it.
- GloballyUniqueIdentifiers (GUIDs) which uniquely identify COM interfaces, COM co-classes, COM objects, etc uniquely in time and space.
- InterfaceDefinitionLanguage (IDL) - A language independent way of uniquely identifying COM Interfaces, their GUIDs, their methods and how parameters are passed in, out or in/out and a way to generate proxy and stub DLLs for marshalling
- An interception Runtime that intercepts all calls and inserts a proxy/stub if necessary
- Location transparency. COM was ALWAYS designed for distributed calls in the beginning. NT4 was the first implementation. The key is that the way you call a COM method on an interface does not change.
- A COM Runtime, implemented in oleaut32.dll, that defines an API set, with CoX.... routines, such as CoCreateInstance(Ex) that locate the object either by looking in the Registry or in the case of COM+ configured components from the COM+ catalog
- Threading Models - STA, MTA, TNA to allow components of various threading types to live where they belong and talk to components of other threading requirements
- Optionally a Type Library generated from the IDL that allows COM to be used from brain-dead scripting languages
COM clients *never* get a pointer to a COM object. They always get a pointer to an interface of that object.
COM does give you a defined interface: IUnknown
, from which all other interfaces must be derived. IUnknown provides for reference counting (via AddRef
/Release) and runtime interface discovery/navigation -- dynamic type casting (via QueryInterface
OLE defines several interfaces to do with object linking and embedding. These interfaces are on top of COM. DirectX defines interfaces for gaming. DirectShow
defines interfaces for media streaming. etc., etc. These are also on top of COM.
MTS was a separate add-on product (NT Option Pack) which leverages this further to provide for other stuff like just-in-time activation (JITA), object pooling (lowers instantiation costs by reusing objects), transactions, etc.
gets its name from COM + MTS + MSMQ + OTHER NEW FEATURES (like the new publish/subscribe event system). ComPlus
merges the COM and MTS object models into one object model and puts the runtime into the kernel. It adds a list of features detailed on the ComPlus
page. It doesn't necessary do anything different with DCOM (DistributedCom
)... DCOM is really just COM over the wire, where location transparency means something more than just being outside an apartment or local process, adding the possibly of communicating with an instance of a component running on entirely different machine.
I'd prefer that this page not degenerate into a ThreadMode
discussion. Ways that I think will avoid this are the following:
- Ask your questions below.
- If you answer a question, refactor the above explanation to include both, and delete the question.
- Please refrain from signing anything, unless you feel the need for DramaticIdentity.
- Keeping this page a PissingMatchFreeZone? - slag COM off on ComIsHard if you feel the need.
As one who has worked with COM since its beta in 1993 and taught it, I went and re-factored the above. -- SamGentile
So, what's the story with Microsoft abandoning shared COM objects as code reuse? That is, storing multiple versions of the same COM object on the system, and then having each application maintain a manifest of the objects and versions they require? Actually, it's naturally because ComponentOrientedProgramming
as code reuse doesn't work at the interface level because the interface isn't implementation. But how does this affect COM's usefulness? Why not just use DLLs (for INPROC COM objects)? I'm not trolling here either; I just don't get it anymore. I love COM, but it seems so useless now. -- SunirShah
I assume you are referring to DotNet
's model and COM being dead. First of all, COM is not dead and COM+ continues to evolve and get new features. DotNet
has each Assembly (not application) maintain a manifest of the objects and versions they require. Why is this a win? Because this gets rid of the COM problem of having to register things in the Registry. This also allows a DotNet
app to use xcopy deployment: you just simply copy all the assemblies and files to some directory and party on. No more registration. No more registry. Your other question I don't understand: COM DOES use DLLs for INPROC COM objects. Let me know if this is not clear. Thanks for your interest. -- SamGentile
Apparently, in the latest versions of Windows (don't know exactly; I'm a Palm developer now), applications will no longer be able to use registered COM objects, but have to use that manifest thing. I recognize the reason being version inconsistencies. This is because component-oriented programming does not create code reuse (nothing does). So, it would seem that it's cheaper for applications to just statically link everything, except for the problem bugfixes and patches.
I don't believe that is true. I am using the latest Whistler and I can still register and use old-style COM objects.
In those cases, splitting the application into modules makes it easier to contain changes to small binaries. However, that doesn't explain what all the complication of COM is good for. A plain vanilla
DLL seems like a better choice than a COM object. You lose the thread model, but that's really not much of an issue anyway.
Why? DLLs can't be versioned. COM Interfaces can be. In Proc COM Objects are DLLs.
Out of process COM objects have advantages, especially if they are persistently loaded and shared. But in process COM objects are just complication and overhead that isn't really necessary.
By the way, a nicer modularization scheme might be like Java's .class system, except that (just like everything in Java ;) it's broken. Perl has a good model too. Reports of C# indicate it's actually doing the right thing, which is super nice. But that doesn't leave much room for COM for normal applications.
Then again, maybe the IDispatch interface is enough reason? Interlanguage operability? I'm not entirely sure about that. DLLs work for that too, in most cases. Maybe a better question is "What does an INPROC COM object do for you now?" -- SunirShah
IDispatch is for dumb VB and scripting languages. DLLs and COM are not really a valid comparison unless you are comparing them for code reuse and then InPROC COM solves is that the lack of a C++ binary standard limits what language features can be used across DLL boundaries. Simply exporting C++ member functions is not enough to create a vendor-independent component substrate. Also, because C++ requires the client knowledge of object layout, C++ introduces a tight binary coupling between the client and object executables. So versioning is impossible. COM solves these issues and more. It allows a client to select and load binary components dynamically that can evolve their implementation layout over time without requiring client recompilation. Also an INPROC COM component provides RTTI of interfaces across multiple vendor's compilers and languages. The last area is resource management. A INPROC COM object can go away when there are no outstanding references.