wideman-one 
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.

Starting point: IDispatch

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.

Potential confusion when looking at an xxx_TLB.pas unit.

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]   wideman-one