670 likes | 808 Views
COMS W4156: Advanced Software Engineering. Prof. Gail Kaiser Kaiser+4156@cs.columbia.edu http://york.cs.columbia.edu/classes/cs4156/. COM Overview. Component Object Model (COM).
E N D
COMS W4156: Advanced Software Engineering Prof. Gail Kaiser Kaiser+4156@cs.columbia.edu http://york.cs.columbia.edu/classes/cs4156/ Kaiser: COMS W4156 Fall 2007
COM Overview Kaiser: COMS W4156 Fall 2007
Component Object Model (COM) • COM specifies an object (or component) model, and programming and compiler requirements, that enable COM objects to interact with other COM objects on the same or different hosts • COM is a binary standard—a standard that applies after a program has been translated to binary machine code • Objects can be written in different languages, including languages that don’t have “objects” Kaiser: COMS W4156 Fall 2007
COM Objects • A COM object is made up of a set of data and the functions that manipulate the data • A COM object’s data is accessed exclusively through one or more sets of related functions • These function sets are called interfaces, and the functions of an interface are called methods • COM requires that the only way to gain access to the methods of an interface is through a pointer to the interface Kaiser: COMS W4156 Fall 2007
COM Interfaces • COM uses a straight line with a circle at the end to denote an interface: • All COM objects are required to implement specific functionality that supports “Interface Navigation” and “Lifetime Management”, by implementing the IUnknown interface • To denote a COM object and its interfaces, COM uses a box with connected interface diagrams: Kaiser: COMS W4156 Fall 2007
IUnknown Interface • Lifetime management • Reference counting mechanism supported by AddRef and Release (both return new reference count) • Reference count begins at 1 when object created, object normally destroyed when count reaches 0 • The different allocation semantics of languages are accommodated by making objects responsible for their own creation and destruction • Interface navigation • Call QueryInterface to get a pointer to another interface supported by the same object (supplied Interface ID = IID, returns success or failure code) Kaiser: COMS W4156 Fall 2007
QueryInterface • Suppose a client has a pointer to interface A on an object and asks for interfaces B and C • Say the object supports interface B but not C • The result is that the object returns a pointer to B and returns a null pointer for C • If one asks an "old" object whether it supports a "new" interface (for example, that was invented after the old object had been shipped), the old object will reliably answer “no”, without causing a crash • Analogous to casting, enabling access to different set of methods (from the accessed interface) Kaiser: COMS W4156 Fall 2007
Example class CMyComObject : public IMyComInterface, public IYourComInterface { HRESULT __stdcall QueryInterface (const IID& iid, void **ppv); ULONG __stdcall AddRef(); ULONG __stdcall Release(); //Methods for IMyComInterface HRESULT __stdcall Fx1(char *buf); HRESULT __stdcall Fx2(); //Methods for IYourComInterface HRESULT __stdcall Zx1(int ix); }; Kaiser: COMS W4156 Fall 2007
Example Kaiser: COMS W4156 Fall 2007
Explanation • All interfaces within an instance of a COM object must always return the same value for IUnknown • The IUnknown pointer is used to identify an instance of a COM object uniquely • So when asked for IUnknown, we returned a pointer to the first interface in the object—IMyComInterface Kaiser: COMS W4156 Fall 2007
Reference Counting Implementation • The conventional implementation uses a member variable as a counter • QueryInterface calls AddRef after a successful assignment of an interface pointer, to increment the counter • The client calls Release when it is finished using an interface pointer, which decrements the reference counter • The interface instance needs to delete itself when the reference count becomes 0 • Clients have to be careful to match AddRef and Release calls when they make extra copies Kaiser: COMS W4156 Fall 2007
Example class CMyComObject : public IMyComInterface, public IYourComInterface { ULONG m_refcnt; ... Same as previous definitions ,,, CMyComObject() : m_refcnt(0) { ; } }; Kaiser: COMS W4156 Fall 2007
Example Kaiser: COMS W4156 Fall 2007
Class Factory • COM objects are instances of a COM class (called a coclass for component object class) and are created by a class factory object • A class factory implements an interface called IClassFactory (or IClassFactory2) • IClassFactory defines a CreateInstance method that creates an instance of a COM object • COM objects reside in servers, which must implement a class factory object for each kind of COM object it can contain • One class object can instantiate multiple kinds of COM objects, given the desired CLSID – a GUID, or the CoCreateInstance COM library API can be used Kaiser: COMS W4156 Fall 2007
Creating a COM Object • A client asks COM for the class factory that knows how to create a specific COM object • COM asks the appropriate COM server for the requested class factory • The server returns a pointer to the class factory's IClassFactory interface to COM • COM returns the pointer to the client • The client uses the CreateInstance method in IClassFactory to create instances of the COM object Kaiser: COMS W4156 Fall 2007
COM Server Kaiser: COMS W4156 Fall 2007
COM Apartment • COM objects are actually created in the context of a COM apartment • A COM apartment defines the threading context of an executing COM object • A single-threaded apartment (STA) allows only one thread to access interface methods within the object • This is always the same thread Kaiser: COMS W4156 Fall 2007
COM Apartment • A multi-threaded apartment (MTA) allows multiple threads to access interface methods within the same object • This access can, and often does, occur simultaneously • For example, thread A and thread B can simultaneously access the same or different methods within the object (code must be re-entrant) Kaiser: COMS W4156 Fall 2007
Apartment Objects • There aren’t any • Unlike COM interfaces, classes and objects, which are visible in code, there is no apartment object • Instead, the type of apartment dictates how to code COM interface methods • In an STA, because only one specific thread can access an instance of a COM object, no special coding is required to guard data and methods • In an MTA, data and methods are guarded using Win32 synchronization objects Kaiser: COMS W4156 Fall 2007
COM Interfaces • COM allows objects to interact across process and machine boundaries as easily as within a single process • COM enables this by specifying that the only way to manipulate the data associated with an object is through an interface on the object • “Interface” here refers to an implementation in code of a COM binary-compliant interface that is associated with an object • COM methods and interfaces must follow a prescribed in-memory layout Kaiser: COMS W4156 Fall 2007
Calling Conventions • COM methods are called using an extension of C/C++ calling conventions • The __stdcall attribute is placed in front of a function to set up this calling convention • Function parameters are pushed onto the stack in right-to-left order (last parameter pushed first) • Caller must clean up the stack after the function call returns • Marshalling/demarshalling method parameters and return values across process and machine boundaries handled by operating system (in Windows COM implementation) Kaiser: COMS W4156 Fall 2007
Return Type • COM methods return type HRESULT • An HRESULT is a 32-bit unsigned integer that indicates the success or failure of a COM call • Core COM methods define specific error codes as HRESULTs • High bit indicates success or failure • Rest (represented in hex) indicates “facility” (storage, windows, security, control, etc.) and specific error (e.g., E_NOTIMPL, E_OUTOFMEMORY, E_NOINTERFACE) Kaiser: COMS W4156 Fall 2007
Processing Error Codes • Two macros are defined to help process error codes: FAILED and SUCCEEDED • Each takes in an HRESULT return value and returns zero or non-zero • Passing in an HRESULT return value that indicates an error condition FAILED will return non-zero, meaning the COM method call returned an error Kaiser: COMS W4156 Fall 2007
Interface Parameter • The first parameter passed to a COM method must be a pointer to the COM interface containing the method being called • For example, COM interface IMyComInterface contains methods Fx1 and Fx2: interface IMyComInterface { HRESULT __stdcall Fx1(CHAR *buf); HRESULT __stdcall Fx2(); }; • COM interface methods must be in a vtable Kaiser: COMS W4156 Fall 2007
Binary Layout Requirements • A vtable is a table of pointers to interface methods • Runtime binary layout of a COM interface contains a vtable • A COM interface pointer is a pointer to a vtable • Taken from C++: C++ compilers place virtual member functions of a class into a vtable Kaiser: COMS W4156 Fall 2007
Vtable Layout • Methods in a vtable are accessed by table position, not by method name • The placement of functions in a vtable is called vtable order • The first three pointers in every vtable associated with a COM interface must point to the IUnknown methods (QueryInterface, AddRef, and Release) in order Kaiser: COMS W4156 Fall 2007
Vtable Layout Kaiser: COMS W4156 Fall 2007
Multiple Interfaces is NOT Multiple Inheritance • COM does not support implementation inheritance • There is no way to inherit member functions and member variables from a base class • However, the standard convention used in COM is to say, "All COM interfaces inherit [or derive from] IUnknown." • This means that all COM objects implement the methods of IUnknown Kaiser: COMS W4156 Fall 2007
Example Interface class CIMyComInterface { //For C++ we usually add //a 'C' in front of the //interface name virtual HRESULT __stdcall QueryInterface (const IID& iid, void **ppv); virtual unsigned long __stdcall AddRef(); virtual unsigned long __stdcall Release(); virtual HRESULT __stdcall Fx1(CHAR *buf); virtual HRESULT __stdcall Fx2(); }; Kaiser: COMS W4156 Fall 2007
Example Discussion • When a pointer to this class is passed to a COM client, the client can't see any part of the object other than the vtable • Data and non-virtual member functions are not visible or accessible • C++ is the “language of choice” for COM Kaiser: COMS W4156 Fall 2007
How Convenient • C++ passes the this pointer as an implicit first parameter • The this pointer of a C++ class instance points to the internal class object built by the C++ compiler • A C++ class with virtual functions contains a vtable to access those functions • Because the vtable is the first object in the C++ class object, the this pointer is in effect a pointer to a pointer to a vtable • Same binary layout as a COM interface Kaiser: COMS W4156 Fall 2007
But COM Interface Different from C++ Interface • COM uses the word interface in a sense different from that typically used in C++ programming • A C++ interface refers to allof the functions that a class supports and that clients of an object can call to interact with it • A COM interface is a pure virtual definition that carries no implementation • A COM interface refers to a predefined group of related functions that a COM class implements, but a specific interface does not necessarily represent allthe functions that the class supports Kaiser: COMS W4156 Fall 2007
Interface Definition Language (IDL) • Define interfaces, classes, structures, enumerations and other user-defined types in a language independent manner • IDL compiler generates type libraries and language-specific code containing definitions that implement COM interfaces • For C/C++, generates header files containing struct definitions to match the vtables of the declared interfaces, a C file containing declarations of the interface GUIDs, and C++ source code for a proxy module (method stubs for converting local calls to RPC) • For other languages (e.g., Visual Basic), the binary metadata contained within the type library is processed by language compilers and runtime environments to produce appropriate language-specific constructs • Important note: COM IDL is not the same as CORBA IDL, and is sometimes called MIDL (Microsoft Interface Definition Language) Kaiser: COMS W4156 Fall 2007
Implementing an Interface • Referring to an object implementing an interface means • The object includes code that implements each method of the interface, and • Provides COM binary-compliant pointers to those functions to the COM library • COM makes those functions available to any client with a pointer to the interface, whether the client is inside or outside of the process that implements those functions • Different object classes may implement an interface differently yet be used interchangeably in binary form Kaiser: COMS W4156 Fall 2007
Multiple Interfaces • COM objects may support several interfaces • Clients have access to a COM object only through a pointer to one of its interfaces, which, in turn, allows the client to call any of the methods that make up that interface (through the QueryInterface method of IUnknown) • These methods determine how a client can use the object's data Kaiser: COMS W4156 Fall 2007
Interface Contracts • An interface defines a contract between an object and its clients • The contract specifies the methods that must be associated with each interface and what the behavior of each of the methods must be in terms of input and output • The contract generally does not define how to implement the methods in an interface Kaiser: COMS W4156 Fall 2007
Interface Contracts • If an object supports an interface, it must support all of that interface's methods in some way • Not all of the methods in an implementation need to do something—if an object does not support the function implied by a method, its implementation may be a simple return or perhaps the return of a meaningful error message—but the method must exist Kaiser: COMS W4156 Fall 2007
Interface Pointers • An instance of an interfaceimplementation is actually a pointer to an array of pointers to methods—that is, a function table (vtable) that refers to an implementation of all of the methods specified in the interface • One can manually create such function tables in a C application or almost automatically by using C++ (or other object-oriented languages with COM support) • Objects with multiple interfaces can provide pointers to more than one function table • Any code that has a pointer (“interface pointer”) through which it can access the array can call the methods in that interface Kaiser: COMS W4156 Fall 2007
Calling an Interface Method • With appropriate compiler support (inherent in C and C++), a client can call an interface method through its name, rather than its position in the array • Because an interface is a type, the compiler, given the names of methods, can check the types of parameters and return values of each interface method call • In contrast, if a client uses a position-based calling scheme, such type-checking is not available, even in C or C++ Kaiser: COMS W4156 Fall 2007
Interface Views • Clients and objects have different views of a COM interface • The object sees the interface implementation via its internal C++ class (or however the interface is presented in the programming language) • The client views the object through its interfaces (its vtables) Kaiser: COMS W4156 Fall 2007
Server vs. Client Views Kaiser: COMS W4156 Fall 2007
COM Clients and Servers • A COM client is whatever code or object gets a pointer to a COM server and uses its services by calling the methods of its interface(s) • A COM server is any object that provides services to clients • These services are in the form of COM interface implementations that can be called by any client that is able to get a pointer to one of the interfaces on the server object Kaiser: COMS W4156 Fall 2007
COM Server Duties • Register all COM classes in the system registry (e.g., register the CLSID, a GUID, under HKEY_CLASSES_ROOT\clsid\{ clsid-xxx }_ • Unregister all of its COM classes • Create class objects and provide pointers to each class object's object creation interface, IClassFactory, to the COM runtime system Kaiser: COMS W4156 Fall 2007
COM Server Duties • Keep track of reference counts on instances of its COM objects and server lock counts • A server's execution can be terminated if none of its COM objects are in use and the lock counts are 0 Kaiser: COMS W4156 Fall 2007
Types of COM Server • An in-processserver resides in a dynamic link library (DLL) and runs in the same address space as the COM client • A localserver resides in its own executable (e.g., *.exe file), in a different process but on the same machine as the COM client • A remote server runs on a different machine than the client Kaiser: COMS W4156 Fall 2007
Same Machine • For clients and servers on the same machine, the CLSID of the server is all the client ever needs • On each machine, COM maintains a database (using the system registry on Windows) of all the CLSIDs for the servers installed on the system • This is a mapping between each CLSID and the location of the DLL or EXE that houses the code for that CLSID • COM consults this database whenever a client wants to create an instance of a COM class and use its services, so the client never needs to know the absolute location Kaiser: COMS W4156 Fall 2007
Different Machines • For distributed systems, COM provides registry entries that allow a remote server to register itself for use by a local client • Applications need know only a server's CLSID, because they can rely on the registry to locate the server • However, COM allows clients to override registry entries and to specify server locations Kaiser: COMS W4156 Fall 2007
COM vs. DCOM • COM client applications do not need to be aware of how server objects are packaged, whether they are packaged as in-process objects (in DLLs) or as local or remote objects (in EXEs) • Distributed COM (DCOM) is not separate—it is just COM with a longer wire Kaiser: COMS W4156 Fall 2007
CLSID • Each COM class is identified by a CLSID, a unique 128-bit GUID, which the server must register • COM uses this CLSID, at the request of a client, to access the DLL or EXE containing the code that implements the class, which then creates an instance of the object (or finds an existing instance) Kaiser: COMS W4156 Fall 2007
Globally Unique Identifier • Each interface is referred to at run time with an IID, which is a globally unique identifier (GUID) • A GUID is a 128-bit number • This IID allows a client to ask an object precisely whether it supports the interface • Eliminates the possibility of duplication that could occur with other naming schemes • Permits multiple versions of the same interface with the same name Kaiser: COMS W4156 Fall 2007