What are the different types of interfaces?
Standard Interfaces
A standard interface represent the collection of interfaces that Microsoft developed and deployed. If you develop a component that supports a standard interface, someone else will be able to use your component because standard interfaces are publicly documented. Standard interfaces are also called as OLE interfaces. IShellLink, IMoniker, IPersist, IConnectionPoint, IDispatch, etc. are examples of standard interfaces.
Custom Interfaces
A custom interface is a user-defined interface that uses VTABLE binding. Suppose you create a component called Math and expose its interface IMath, then IMath is the custom interface. Since a client from a different machine may use this component, we must provide a proxy/stub DLL that contains the marshaling code for our custom interface. Also, the interface identifier (IID) of our custom interface must be registered before a client can communicate with our COM object. Custom interfaces do not support dynamic invocation. Thus, everything must be known at compile time.
Automation Interfaces
An Automation interface is a user-defined interface that supports dynamic invocation and late binding via the IDispatch interface. The advantage of an Automation interface is that a wide range of clients including scripting clients can use it. Also, we don’t have to create proxy/stub DLLs because Microsoft provides generic marshaling code in the Automation marshaler (oleaut32.dll). Instead of using proxy/stub DLLs, the Automation marshaler uses a type library, which stores detailed type information regarding objects and their supported interfaces. The only disadvantage of an automation interface is that it supports only Automation compatible data types.
Dual Interfaces
A dual interface is the one which supports the IDispatch as well as VTABLE binding. IDispatch permits dynamic invocation thereby letting even the scripting clients use your component, whereas, VTABLE permits faster access to the interface methods. One drawback of this technique is that we have to use Automation compatible types, such as BSTR and VARIANT. Also, all interface methods must return a HRESULT.
What is an HRESULT?
COM component methods use HRESULTs to report error/success conditions to their users. For example, methods like CoCreateInstance( ), QueryInterface( ), CLSIDFromProgID( ), all return an HRESULT. Most COM interface methods return a HRESULT. While the name HRESULT might make you think an HRESULT is a handle to a result. it isn’t. A HRESULT is a 32-bit value divided into three different fields. The left-most bit reports the success/failure of the method. The right-most 16 bits contain the return code (reason for success/failure). The middle 15 bits provide more information about the type and the origin of the return code. This is often known as the facility code.
By convention successful return codes begin with an S_, while failure codes begin with an E_. Meanings of some of the commonly used return codes are given below.
| Name | Meaning |
| S_OK | Function succeeded and is returning a Boolean true. S_OK is defined as 0. |
| S_FALSE | Function succeeded and is returning a Boolean false. S_FALSE is defined as 1. |
| E_UNEXPECTED | Unexpected failure. |
| E_NOTIMPL | Member function is not implemented. |
| E_NOINTERFACE | Component does not support requested interface. |
| E_OUTOFMEMORY | Component could not allocate required memory. |
| E_FAIL | Unspecified failure. |
Note that S_FALSE is defined as 1 and S_OK is defined a 0. These definitions are contrary to traditional C/C++ programming principles, according to which o is false and nonzero is true. Therefore, when you use HRESULTs be sure you explicitly compare the return values to S_FALSE or S_OK.
The facility code identifies the part of the operating system that can return the return code. The currently defined facility codes are listed below:
-
FACILITY_WINDOWS 8
-
FACILITY_STORAGE 3
-
FACILITY_SSPI 9
-
FACILITY_RPC 1
-
FACILITY_WIN32 7
-
FACILITY_CONTROL 10
-
FACILITY_NULL 0
-
FACILITY_ITF 4
-
FACILITY_DISPATCH 2
-
FACILITY_CART 11
If one team of Microsoft developers decide to return a return code of 2 to signify some error condition, there is a possibility that another team too decides to return a return code of 2, this time signifying a totally different error condition. This would lead to a conflict. This conflict is sorted out through the facility codes. One team can return a 2 in return code so long as each of them returns a different facility code.
To determine the facility of an HRESULT use the macro HRESULT_FACILITY defined in WINERROR.H. To determine whether the method returned success or failure we can use the macros FAILED and SUCCEEDED.
What do you mean by Location transparency?
When a client uses a COM component it believes that the component is available locally on the same machine as the client. However, the component can be anywhere in cyberspace. It could live in the same process as the client, a different process on the same machine, or a process on a machine hundreds of miles away. From the client’s perspective, it doesn’t matter where the component is physically residing. This is the idea behind Location Transparency.
Location transparency is achieved using a concept called marshalling. To support marshalling, COM uses a previous, proven technology known as RPC. RPC supports location transparency in the functional world. COM, which is built on top of RPC supports location transparency in the object-oriented world. To carry out communication between the client and the server COM uses an interface to define a set of related functions. From this interface, using the Microsoft Interface Definition Language (MIDL) compiler, we can generate the corresponding marshalling code. This marshalling code is also known as proxy/stub code.
When a remote method invocation is made the proxy/stub code gets into action. The client calls a method as if the method exists in the current process. In reality, the proxy code will intercept the call. The job of this code is to marshal the intelligent data into a raw buffer and send the raw buffer to an interface stub on the machine where the component is present. When the interface stub receives the raw buffer, it unmarshals the buffer into a format that it can use to invoke the actual interface method in the component. When the call returns to the interface stub, the interface stub marshals the return values into a raw buffer, and sends the buffer back to the interface proxy. After the interface proxy receives the raw buffer, it unmarshals the return data for the client.
Location transparency offers a number of advantages. These are:
-
It permits us to write code that talks to a component without worrying about where the component is actually present.
-
The fact that object can be located anywhere permits greater flexibility in distribution.
-
Location transparency also allows greater scalability. If a component is overloaded, you can add new ones to form a cluster of components. A referral component can then be built to route clients to appropriate components.
-
Location transparency offers fault tolerance. For example, if a particular component fails the client can be referred to a different component without the client even realizing it.
0 comments:
Post a Comment