Interfaces are the heart of COM. They distinguish between a contract used between the client and the object, and the implementation.
The interface (the contract) defines the methods that are offered by the component and that can be used by the client. With .NET, interfaces play an important part, too.
COM distinguishes among three interface types: custom, dispatch, and dual interfaces.
Custom interfaces derive from the interface IUnknown.
A custom interface defines the order of the
methods in a virtual table (vtable), so that the client can access the methods of the interface directly.
This also means that the client needs to know the vtable during development time, because binding to the
methods happens by using memo~ addresses. As a conclusion, custom interfaces cannot be used by scripting clients.
shows the vtable of the custom interface IMath that offers the methods Add () and Sub () in addition to the methods of the IUnknown interface.
Because a scripting client (and earlier Visual Basic clients) doesn’t support custom interfaces, a different interface type is needed.
With dispatch interfaces, the interface available for the client is always the IDispatch interface. IDispatch derives from IUnknown and offers four methods in addition to the IUnknown methods.
The two most important methods are GetIDsOfNames () and Invoke with a dispatch interface two tables are needed. The first one maps the method or property name to a dispatch ID; the second one maps the dispatch ID to the implementation of the method or property.
→ Querylnterface → ‘Add’ 47
AddRef → ‘Sub’ 48
GetlDsOfNames → 47 pAdd→
Invoke → 48 pSub→
When the client invokes a method in the component, at first it calls the method GetIDsOfNames ( ), passing the name of the method it wants to call.
GetIDsOfNames () makes a lookup into the name-to-ID
table to return the dispatch ID. This ID is used by the client to call the Invoke () method.
Usually, the two tables for the IDispatch interface are stored inside the type library, but this is not a requirement, and some components have the tables in other places.
As you can imagine, dispatch interfaces are a lot slower than custom interfaces.
On the other hand, custom interfaces cannot be used by scripting clients.
A dual interface can solve this dilemma.
As you can see in Figure 24-3, a dual interface is derived from IDispatch but offers the additional methods of the interface directly in the vtable.
Scripting clients can use the IDispatch interface to invoke the
methods, whereas clients aware of the vtable can call the methods directly.
→Querylnterface →~ ‘Add’ 47
AddRef ‘Sub’ 48
Invoke → ~ 47 pAdd →
Add → 48 psub →
Casting and Querylnterface.
If a .NETclass implements multiple interfaces, casts can be done to get one interface or another.
With COM, the interface IUnknown offers a similar mechanism with the method Query interface ().
As discussed in the previous section, the interface IUnknown is the base interface of every interface,so
QueryInterface () is available anyway.