Last edit: 05-03-17 Graham Wideman |
Delphi |
Automation Interface Confusions Straightened Out Article created: 99-04-30 Major revision: 98-07-28 |
This page sorts out some confusions over Microsoft's names for various key Automation-related features. It is not particular to Delphi, in fact much of this is hidden when using Delphi to control an Automation server. However, if you are implementing an Automation client, even though Delphi makes it easy, you will encounter this confusing naming mess.
An application or module offers automation service by implementing and making available the IDispatch interface. Confusion arises because there are three different levels of Automation/IDispatch-related functionality that a server may or may not implement, and thus three ways that an automation controller can access the server's Automation interface. The alternatives are tabulated below.
Graham's description |
Automation terminology, binding. |
Server class Class_MyAuto in server Srv provides implementation for | Delphi-style code | Behind the scenes call sequence |
Call using OLEVariant | variant late |
IMyAuto, which implements
IDispatch. (Plus internal functions and data not directly callable.) |
MyOleVariant: OleVariant [...] CreateOleObject('Srv.MyAuto') [...] MyOleVariant.myfunc |
IMyAuto.GetIDsOfNames('myfunc',...) IMyAuto.Invoke(DispId,...) --> myfunc |
Call using member id number DispId | dispinterface Member address resolved "late", but DispId resolved by compiler |
IMyAuto, which implements
IDispatch. Declaration for IMyAuto as dispinterface, say IMyAutoDisp (Plus internal functions and data not directly callable.) |
MyDispIntf: IMyAutoDisp [...] CreateComObject(Class_MyAuto) as IMyAutoDisp; [...] MyDispIntf.myfunc |
IMyAuto.Invoke(DispId,...) --> myfunc |
Call using member
address (ie: using VTBL) |
"interface" (ambiguous term) early binding |
IMyAuto which includes and extends IDispatch with the addition of directly-callable member functions and properties. (Note that IMyAuto "interface" subsumes variant-accessible interface.) | MyIntf: IMyAuto [...] CoMyAuto.Create [...] MyIntf.myfunc |
IMyAuto.myfunc |
dual -- supports both interface and dispinterface. | If server implements extended IMyInterface, then, might as well implement the dispinterface as well. (Tools generate both automatically.) | . | . |
Ambiguities:
The call-using-member-address scheme is known as an "interface" or "Automation interface", while the other two schemes are also loosely refered to as interfaces. (So the call-using-member-address scheme should be called an "interface interface" or what?)
Delphi Object Pascal note: The variants used here for automation objects or for some automation function parameters are type "OleVariant", not the Pascal type "variant"... which accomodates a more general assortment of types.
Delphi users wanting to control an automation server will generally use the Delphi "Import Type Library" function to produce and xxx_TLB.pas unit, which declares the interfaces exposed by the server in question.
Browsing the declarations for a dual interface, you may notice that the declaration of the "interface" (ie: call-using-member-address interface) clearly inherits the declaration of IDispatch. Confusingly, "IDispatch" never appears in the declaration of the corresponding dispinterface. This is because the dispinterface section is not an interface declaration per se -- instead it's a special syntax used to indicate that, given that the server has an implementation of IDispatch, here are the functions that you can access through that IDispatch's Invoke method, and the DispIds for each one.
Go to: ["Up" to Main Delphi Page]