Containment Delegation  «Prev  Next»
Lesson 4 Integrating components: COM component advantages
Objective Understand the advantages of integrating COM components.

Integrating Components and COM Component Advantages

Elvis does not have to rebuild his code because it has no source-code based dependencies on any interfaces or objects in CBIComp.dll. The include files used for interface definitions contained in COM objects within CBIComp.dll define only vtable order and parameters. Recall that these methods are all defined as pure virtual, and COM interface pointers are not instantiated by new. Instead, the address of the pointer is passed into IClassFactory::CreateInstance (directly or via CoCreateInstance) or IUnknown::QueryInterface. These calls are implemented by a class factory or COM object within the server. The server allocates memory for the COM object and its interfaces, and assigns the interface pointer into the caller's pointer. The integration between a COM object and client is through the object's CLSID and interface specifications only--that is, a COM class. The actual hookup of client code to a COM object is done at runtime. As long as the object's CLSID and interface definitions remain unchanged, component users can safely integrate with components without rebuilding their applications. To support this, we say that all COM interfaces are immutable that is, once a COM interface is published or distributed, it can't change. This lesson demonstrated how COM clients and objects integrate at a binary level. In following lessons, we will examine how software components support reusability.

Interface is not allowed to change

The phrase "COM interfaces are immutable" means that once a COM interface is published or deployed, its specification is not allowed to change. This applies even if different COM objects implement that interface. For example, once interface IX1 is published or deployed, all COM objects that implement IX1 must implement the interface exactly as specified. So if IX1 has the following IDL (interface definition language) definition:
[object,uuid(...)]
interface IX1 : IUnknown
{
   HRESULT x1(int ix);
   HRESULT x2();
}

All COM objects that implement IX1 must implement x1 and x2 in vtable[1] order with the specified parameters.
This does not mean that IX1 will have the same implementation in different COM objects. It means only that the vtable ordering and method parameters remain the same. Consider the case of IUnknown. All COM objects implement QueryInterface, AddRef, and Release in vtable order with exactly the same parameters. However, a call to QueryInterface in one object can have a different implementation than a call to QueryInterface in another object because the objects probably support different interfaces.
  • Interface: An interface is a set of method prototypes. To utilize a method of an interface, a client should get a pointer to the interface. This pointer, if available, is returned by QueryInterface upon request by a client. Every component is required to have an IUnknown interface. A client program, which has requested the system to instantiate a component, will have a pointer to the component. Using this pointer and the QueryInterface method of the IUnknown interface, a client can get a pointer to any interface available from the component. Calling the QueryInterface method asking for an interface is called interface negotiation. Interface negotiation is reflexive, symmetric, and transitive, which is also known as an equivalence relation in discrete mathematics.
  • Component: From a client's point of view, a component is a unit of object instantiation at run time. From the point of view of the code, a component is a house for a collection of interfaces. A compiled and linked component is stored in a container file with extension .exe or .dll that can be accessed during run time by a client. Every container is equipped with an instantiator that is called by the operating system when needed.

Statements about the Component Object Model (COM)

  1. An interface is a set of method prototypes. In COM, an interface is a collection of related method declarations (prototypes) without implementations. These methods define a contract that COM objects agree to fulfill.
  2. To utilize a method of an interface, a client should get a pointer to the interface. Clients interact with COM objects through interface pointers. Before calling any method, a client must obtain a pointer to the desired interface.
  3. This pointer, if available, is returned by `QueryInterface` upon request by a client.The `QueryInterface` method is used to obtain pointers to different interfaces implemented by a COM object. If the requested interface is supported, `QueryInterface` returns a pointer to it.
  4. Every component is required to have an `IUnknown` interface. `IUnknown` is the base interface from which all COM interfaces derive. It includes the methods `QueryInterface`, `AddRef`, and `Release`, which are essential for interface negotiation and reference counting.
  5. A client program, which has requested the system to instantiate a component, will have a pointer to the component. Using this pointer and the `QueryInterface` method of the `IUnknown` interface, a client can get a pointer to any interface available from the component.Upon instantiation, the client receives a pointer to one of the object's interfaces, typically `IUnknown` or a default interface. The client can then use `QueryInterface` to navigate to other interfaces implemented by the object.
  6. Calling the `QueryInterface` method asking for an interface is called interface negotiation. This process is known as interface negotiation. It allows clients to discover and obtain pointers to interfaces supported by a COM object at runtime.
  7. Interface negotiation is reflexive, symmetric, and transitive, which is also known as an equivalence relation in discrete mathematics. In COM, `QueryInterface` must adhere to the following properties:
  • Reflexive: An interface must be able to return a pointer to itself when `QueryInterface` is called with its own identifier (IID).
  • Symmetric: If a client can obtain interface B from interface A, then it must be possible to obtain interface A from interface B.
  • Transitive: If a client can get from interface A to interface B and from interface B to interface C, then the client must be able to get directly from interface A to interface C.

These properties ensure consistent and predictable behavior in interface navigation, mirroring the characteristics of an equivalence relation in discrete mathematics.
Summary:
  • Interfaces in COM are contracts defined by method prototypes.
  • Interface pointers are essential for clients to interact with COM objects.
  • `IUnknown`interface is mandatory for all COM objects and provides fundamental methods for interface management.
  • `QueryInterface`method is used for interface negotiation, allowing clients to discover supported interfaces.
  • Interface negotiation properties (reflexivity, symmetry, transitivity) ensure reliable and logical navigation between interfaces.

Conclusion: Your statements accurately describe key aspects of COM's architecture and the principles governing interface negotiation. Understanding these concepts is crucial for working with COM, especially when dealing with interface inheritance and object lifetime management.

Integration Com Client Objects - Quiz

Click the Quiz link below to check your understanding of COM client and interface integration.
Integration COM Client Objects - Quiz
[1]vtable aka virtual table: For every class that contains virtual functions, the compiler constructs a virtual table, vtable. The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable.

SEMrush Software