Access Type
Regardless of its location, a COM components can be accessed either through OLE Automation or directly through the interface's virtual table.
Automation
Accessing a COM component through Automation means using a well-known interface called IDispatch to access to a group of methods and properties. This interface includes the method
One advantage of this approach is that the interface has a known virtual table layout. As a result, Windows can include a built-in marshaler for that interface (See Deeper into COM for information on marshalers). The supported types (known as Automation types) and their Eiffel equivalents are listed in the following table:
COM Type | Eiffel equivalent | Description |
VARIANT_BOOL | BOOLEAN | Standard boolean |
unsigned char | CHARACTER | Standard character |
double | DOUBLE | Standard double |
float | REAL | 4-byte real value |
int | INTEGER | Standard integer |
long | INTEGER | Standard integer |
short | INTEGER | 2-byte integer |
BSTR | STRING | Standard string |
CURRENCY | ECOM_CURRENCY | Currency value |
DATE | DATE_TIME | Standard date |
SCODE | INTEGER | Return status |
Interface IDispatch * | ECOM_INTERFACE | Automation interface |
Interface IUnknown * | ECOM_INTERFACE | Generic interface |
dispinterface | ECOM_INTERFACE | Automation interface |
Coclass Typename | TYPE_NAME | Component main class |
SAFEARRAY(TypeName) | ECOM_ARRAY [TypeName] | Array |
TypeName* | CELL [TypeName] | Pointer to type |
VARIANT | ECOM_VARIANT | Variant value |
enum | INTEGER | Enumeration |
Decimal | ECOM_DECIMAL | Decimal value |
Another advantage is a more dynamic discovery of the methods and properties of a component at runtime. Indeed the IDispatch interface also includes methods to determine whether or not a method or property is available and, in the case that it is available, get its identifier. This process is called late binding and allows component to discover at runtime the availability of functionality on other components.
This approach has also a lot of drawbacks. First, late binding is not an efficient way of calling a function on an interface. This is because first its identifier must be requested, and then the function called. That's two round trips which can be expensive in a distributed environment. Second, since the marshaler is built-in, it has to know in advance all the possible types that a function can accept to be able to marshal the corresponding data. Consequently, there is a limitation on the number of types that one can use in signatures of functions on an Automation compatible interface. The set of available types is called Variant and cover most of the standard types. It does not allow however the passing of complex user defined data types.
For these reasons Automation is mostly used in scripting environments (where speed is not an important factor) to accomplish simple tasks.
Direct Access
Direct interface access is the preferred way to access remote servers where speed becomes a concern and data types are specific to the application. The first interface pointer on the component is obtained through the class object (see Class Object ). Other interfaces on the component are obtained by calling the QueryInterface function.
Because information on any interface cannot be accessed dynamically, the description of the interfaces must be provided to tools that need to handle the components such as the EiffelCOM wizard. The official way of describing components and interfaces is through Interface Definition Language (IDL). Once an IDL file has been written to describe a component it can be compiled with MIDL (the Microsoft IDL compiler) to generate both a type library and the code for the marshaler specific to that interface.
EiffelCOM
One idea behind EiffelCOM is that the details of how a component is accessed should be of no concern to an EiffelCOM programmer. Of course the programmer should be able to choose which kind of access he or she wants to use, but this choice should have no impact on the design of the Eiffel system itself. For that reason, the Eiffel code generated by the wizard follows the same architecture independently of the choice made for interface access and marshaling. The differences in access are handled in the EiffelCOM runtime library where the actual calls to the components are implemented.