COM Introduction


Published on

Published in: Technology
1 Comment
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

COM Introduction

  1. 1. COM: A Brief Introduction Dan Berger [email_address]
  2. 2. Outline <ul><li>A Brief History of COM </li></ul><ul><li>Objects vs. Components </li></ul><ul><li>COM as a (C++)++ </li></ul><ul><li>The What and How of COM </li></ul><ul><li>COM as CORBA-light </li></ul><ul><li>The Definitive References </li></ul>
  3. 3. A Brief History of COM <ul><li>The Brain Child of Anthony Williams – outlined in two (internal) MS papers: </li></ul><ul><ul><li>Object Architecture: Dealing with the Unknown or Type Safety in a Dynamically Extensible Class (1988) </li></ul></ul><ul><ul><li>On Inheritance: What It Means and How To Use it (1990) </li></ul></ul>
  4. 4. History (Cont.) <ul><li>Origins of COM were OLE (Object Linking and Embedding) 1 that shipped with Windows 3.1 (1992) </li></ul><ul><li>The first public version of COM shipped in OLE 2.0 (1993). </li></ul><ul><li>DCOM (Distributed COM) was released in 1996 in answer to CORBA. (We’ll ignore it.) </li></ul><ul><li>COM+ was released along with Windows 2000 and was primarily concerned with MTS. The DCOM moniker was dropped. </li></ul>
  5. 5. Objects vs. Components <ul><li>“ Object Oriented Programming = Polymorphism + (Some) Late Binding + (Some) Encapsulation + Inheritance </li></ul><ul><li>Component Oriented Programming = Polymorphism + (Really) Late Binding + (Real, Enforced) Encapsulation + Interface Inheritance + Binary Reuse” </li></ul><ul><ul><ul><li>Charlie Kindel “COM Guy” Microsoft Corp. 9/97 </li></ul></ul></ul>
  6. 6. COM as (C++)++ (Adapted From [2]) <ul><li>If you “get” this, it’s all down hill from here. </li></ul><ul><li>In C++, in particular, the linkage model makes binary distribution and reuse difficult. </li></ul><ul><li>Consider: You’ve written a class that’s part of a C++ class library. </li></ul>
  7. 7. Challenges of Distribution <ul><li>Imagine we distribute the source for the class (as is common in C++ class libraries). </li></ul><ul><ul><li>If each application that uses it statically links it, it gets duplicated (waste) and is impossible to update/fix in the field without redistributing a new application. </li></ul></ul><ul><ul><li>If it’s packaged as a shared library/object, the lack of binary standardization moves the problem to one of interoperation. </li></ul></ul><ul><ul><ul><li>The DLL model (but not the .so model) can actually deal with this lack of standardization, but it’s not pretty. </li></ul></ul></ul>
  8. 8. Challenges of Encapsulation <ul><li>Assume we side-step the compiler/linker trouble. The coast still isn’t clear. The C++ standard also lacks any standard definition for binary encapsulation. </li></ul><ul><li>So changes to the internals of an object that don’t change it’s interface can (and do) break code that uses the object. </li></ul><ul><ul><li>Consider adding private member variables. </li></ul></ul>
  9. 9. Versioned Libraries <ul><li>A quick look in /usr/lib or %WINDIR% will likely reveal a number of “identical” libraries with different versions. </li></ul><ul><ul><li> </li></ul></ul><ul><ul><li> </li></ul></ul><ul><li>With enough diligence the library developer can insulate applications from change buy explicitly versioning the library. </li></ul><ul><ul><li>I think we all agree this is sub-optimal solution. </li></ul></ul>
  10. 10. Interface v. Implementation <ul><li>C++ supports separation of interface and implementation at the syntax level – not at the binary level. </li></ul><ul><ul><li>So changes of the implementation are “seen” by clients. </li></ul></ul><ul><li>We could hide the actual implementing class behind an opaque pointer in the interface exposed to the client and delegate interface calls through this pointer to the “real” object. </li></ul><ul><ul><li>Easy for simple, cumbersome for complex interfaces </li></ul></ul>
  11. 11. Abstract Classes as Interfaces <ul><li>With three assumptions, we can use abstract classes to solve these problems: </li></ul><ul><ul><li>C-style structs are represented identically across (C++) compilers. </li></ul></ul><ul><ul><li>All compilers can be forced to use common call conventions. </li></ul></ul><ul><ul><li>All compilers on a platform use equivalent virtual call implementations. </li></ul></ul>
  12. 12. vtbls and vptrs <ul><li>Assumption 3 is critical, and turns out to be not unfounded, as nearly all C++ compilers use vptrs and vtbls. </li></ul><ul><li>For each class the compiler generates a (static) array of func pointers to it’s members (it’s vtbl). </li></ul><ul><li>Each instance of each class has a (hidden) member that points to the vtbl (it’s vprt). </li></ul>
  13. 13. Example <ul><li>class ISearchableString { </li></ul><ul><li>public: </li></ul><ul><li>virtual int Length(void) const = 0; </li></ul><ul><li>virtual int Find(const char *s) = 0; </li></ul><ul><li>}; </li></ul>IsearchableString vptr vtbl Length (null) Find (null)
  14. 14. Example (cont.) <ul><li>class SString : public ISearchableString { public: </li></ul><ul><ul><li>SearchableString(const char *s); </li></ul></ul><ul><ul><li>~SearchableString(void); int Length(void) const; int Find(const char *s); }; </li></ul></ul>SString vptr vtbl SString::Length SString::Find
  15. 15. Instantiating an Abstract Class <ul><li>Clearly the client can’t instantiate an ISearchableString – it’s pure abstract, nor do we want them instantiating a SString – that breaks (binary) encapsulation. </li></ul><ul><li>So we need a factory method – and we can force it (using extern “C”) to be accessible to all clients. </li></ul>
  16. 16. Virtual Destructors <ul><li>Unfortunately, there’s a problem – our class lacks a virtual d’tor – so calls to delete will use the (default) d’tor on the ISearchableString class. </li></ul><ul><li>We can’t add a virtual d’tor to the abstract class because different compilers put dtor’s in different places in the vtbl. (blech) </li></ul><ul><li>So we add a virtual “Delete” method to the abstract class. </li></ul>
  17. 17. What is COM <ul><li>A “substrate” for building re-usable components. </li></ul><ul><li>Language neutral </li></ul><ul><ul><li>it’s easier to use in C++, but can be used from any language that can generate/grok vtbl’s and vptrs. </li></ul></ul><ul><ul><li>Interfaces are defined in COM IDL (IDL+COM extensions for inheritance and polymorphism) </li></ul></ul><ul><li>OS Neutral </li></ul><ul><ul><li> commercial Unix implementations, and MS supports COM on Mac System (OS X?) </li></ul></ul><ul><ul><li>Using only on the COM spec, we (OMKT) rolled our own. </li></ul></ul>
  18. 18. Interfaces <ul><li>Interfaces are uniquely identified by UUID’s (often called GUID’s – the terms are equivalent) called their IID (interface ID). </li></ul><ul><li>Implementers of an interface are uniquely identified by a UUID called their CLSID (class ID). </li></ul><ul><li>All COM objects implement the IUnknown interface. </li></ul>
  19. 19. IUnknown <ul><li>Provides three methods: </li></ul><ul><ul><li>HRESULT QueryInterface(IID iid, void **ppv) </li></ul></ul><ul><ul><li>ULONG AddRef(void); </li></ul></ul><ul><ul><li>ULONG Release(void); </li></ul></ul><ul><li>AddRef and Release are for resource management (reference counting). We’ll mostly ignore them. </li></ul>
  20. 20. QueryInterface <ul><li>QueryInterface is essentially a run-time cast – it allows you to ask a component if it implements a specific interface. </li></ul><ul><ul><li>If it does, it returns a pointer to that interface pointer in ppv. </li></ul></ul><ul><ul><li>Think of it as a compiler/language neutral dynamic_cast operation. </li></ul></ul>
  21. 21. HRESULT <ul><li>This is language neutral – so no exceptions. HRESULTS are a packed bit field return value used all over COM. </li></ul><ul><ul><li>Honestly it’s one of the ugliest parts of COM. </li></ul></ul><ul><li>The most used return value is defined as S_OK (success, ok), the other is E_FAIL (error, failure) but there are others. </li></ul><ul><li>There are macros SUCCEEDED() and FAILED() that take an HRESULT and report success or failure. </li></ul>
  22. 22. Instantiating Objects <ul><li>So as developers, we have interfaces (defined in IDL) for the components available in a library/on the system. </li></ul><ul><li>How do we actually obtain an instance of an object we want to use? </li></ul><ul><ul><li>In COM this is termed Activation – there are three basic types, and each involves the SCM (service control manager). </li></ul></ul>
  23. 23. Activation and the SCM <ul><li>The SCM manages the mapping between IIDs, CLSIDs, and implementations. </li></ul><ul><li>You can ask the SCM for a particular CLSID and it will instantiate an instance and return it’s interface pointer. </li></ul><ul><ul><li>CoGetClassObject() </li></ul></ul><ul><li>There’s an additional layer of indirection through ProgIDs – strings of the form libraryname.classname.version that map to CLSIDs. </li></ul>
  24. 24. Activation (cont.) <ul><li>Sometimes you want “an implementation of the following interface that meets some set of constraints” </li></ul><ul><ul><li>enter category IDs (CATIDs) </li></ul></ul><ul><li>You can define a set of categories, and each COM class can advertise the categories it implements. </li></ul>
  25. 25. COM as CORBA-light <ul><li>COM provides a very efficient in-process component model. </li></ul><ul><ul><li>Once past the initial COCreateInstance and QueryInterface calls, each method call is simply a call-by-func-pointer call, essentially free. </li></ul></ul><ul><li>Instantiating a component doesn’t require any out of process, or shared memory operations – it’s all DLL (or Shared Object) magic. </li></ul>
  26. 26. There’s Much, Much More <ul><li>COM is specific about many topics that C++ (and other languages) are not. It specifies: </li></ul><ul><ul><li>Execution environment options (so-called Apartments) </li></ul></ul><ul><ul><li>Inter-process Marshalling </li></ul></ul><ul><ul><li>Remote Object Activation mechanism and protocols </li></ul></ul><ul><ul><li>Threading models </li></ul></ul>
  27. 27. The Definitive References <ul><li>[1] The Component Object Model Specification </li></ul><ul><ul><li>Microsoft and Digital Equipment Corp, 1992-1995 </li></ul></ul><ul><ul><li> </li></ul></ul><ul><li>[2] Essential COM </li></ul><ul><ul><li>Don Box, Addison Wesley </li></ul></ul><ul><ul><li>ISBN 0-201-63446-5 </li></ul></ul>