IDL allows you to call the underlying COM object’s methods by calling methods on the IDLcomIDispatch object. IDL handles conversion between IDL data types and the data types used by the component, and any results are returned in IDL variables of the appropriate type.

As with all IDL objects, the general syntax is:

result = ObjRef -> Method([Arguments])

or

ObjRef -> Method[, Arguments]

where ObjRef is an object reference to an instance of a dynamic subclass of the IDLcomIDispatch class.

Function vs. Procedure Methods


In COM, all object methods are functions. IDL’s implementation of the IDLcomIDispatch object maps COM methods that supply a return value using the retval attribute as IDL functions, and COM methods that do not supply a return value via the retval attribute as procedures. See Displaying Interface Information using the Object Viewer for more information on determining which methods use the retval attribute.

The IDLcomIDispatch::GetProperty and IDLcomIDispatch::SetProperty methods are special cases. These methods are IDL object methods, not methods of the underlying COM object, and they use procedure syntax. The process of getting and setting properties on COM objects encapsulated in IDLcomIDispatch objects is discussed in Managing COM Object Properties.

Note: The IDL object system uses method names to identify and call object lifecycle methods (Init and Cleanup). If the COM object underlying an IDLcomIDispatch object implements Init or Cleanup methods, they will be overridden by IDL’s lifecycle methods, and the COM object’s methods will be inaccessible from IDL. Similarly, IDL implements the GetProperty and SetProperty methods for the IDLcomIDispatch object, so any methods of the underlying COM object that use these names will be inaccessible from IDL.

What Happens When a Method Call Is Made


When a method is called on an IDLcomIDispatch object, the method name and arguments are passed to the internal IDL COM subsystem, where they are used to construct the appropriate IDispatch method calls for the underlying COM object.

From the point of view of an IDL user issuing method calls on the IDLcomIDispatch object, this process is completely transparent. The IDL user calls the COM object’s method using IDL syntax, and IDL handles the translation.

Data Type Conversions


IDL and COM use different data types internally. It is ideal to know the types of data expected by the COM object’s methods and the types it returns, but you do not need to manually convert between IDL data types and COM data types. IDL’s dynamic type conversion facilities handle all conversion of data types between IDL and the COM system. The data type mappings are described in COM-IDL Data Type Mapping.

For example, if the COM object that underlies an IDLcomIDispatch object has a method that requires a value of type INT as an input argument, you would supply the value as an IDL Long. If you supplied the value as any other IDL data type, IDL would first convert the value to an IDL Long using its normal data type conversion mechanism before passing the value to the COM object as an INT.

Similarly, if a COM object returns a BOOL value, IDL will place the value in a variable of Byte type, with a value of 1 (one) signifying True or a value of 0 (zero) signifying False.

Optional Arguments


Like IDL routines, COM object methods can have optional arguments. Optional arguments eliminate the need for the calling program to provide input data for all possible arguments to the method for each call. The COM optional argument functionality is passed along to COM object methods called on IDLcomIDispatch objects, and to the IDLcomIDispatch::GetProperty method. This means that if an argument is not required by the underlying COM object method, it can be omitted from the method call used on the IDLcomIDispatch object.

Note: Only method arguments defined with the optional token in the object’s interface definition are optional. See Displaying Interface Information using the Object Viewer for more information regarding the object’s interface definition file.

Note: If an argument that is not optional is omitted from the method call used on the IDLcomIDispatch object, IDL will generate an error.

Argument Order

Like IDL, COM treats arguments as positional parameters. This means that it makes a difference where in the argument list an argument occurs. (Contrast this with IDL’s handling of keywords, which can occur anywhere in the argument list after the routine name.) COM enforces the following ordering for arguments to object methods:

  1. Required arguments
  2. Optional arguments for which default values are defined
  3. Optional arguments for which no default values are defined

The same order applies when the method is called on an IDLcomIDispatch object.

Default Argument Values

COM allows objects to specify a default value for any method arguments that are optional. If a call to a method that has an optional argument with a default value omits the optional argument, the default value is used. IDL behaves in the same way as COM when calling COM object methods on IDLcomIDispatch objects, and when calling the IDLcomIDispatch::GetProperty method.

Method arguments defined with the defaultvalue() token in the object’s interface definition are optional, and will use the specified default value if omitted from the method call. See Displaying Interface Information using the Object Viewer for more information regarding the object’s interface definition file.

Argument Skipping

COM allows methods with optional arguments to accept a subset of the full argument list by specifying which arguments are not present. This allows the calling routine to supply, for example, the first and third arguments to a method, but not the second. IDL provides the same functionality for COM object methods called on

IDLcomIDispatch objects, but not for the IDLcomIDispatch::GetProperty or SetProperty methods.

To skip one or more arguments from a list of optional arguments, include the SKIP keyword in the method call. The SKIP keyword accepts either a scalar or a vector of numbers specifying which arguments are not provided.

Note: The indices for the list of method arguments are zero-based. That is, the first method argument (either optional or required) is argument 0 (zero), the next is argument 1 (one), etc.

For example, suppose a COM object method accepts four arguments, of which the second, third, and fourth are optional:

ObjMethod, arg1, arg2-optional, arg3-optional, arg4-optional

To call this method on the IDLcomIDispatch object that encapsulates the underlying COM object, skipping arg2, use the following command:

objRef->ObjMethod, arg1, arg3, arg4, SKIP=1

Note that the SKIP keyword uses the index value 1 to indicate the second argument in the argument list. Similarly, to skip arg2 and arg3, use the following command:

objRef->ObjMethod, arg1, arg4, SKIP=[1,2]

Finally, note that you do not need to supply the SKIP keyword if the arguments are supplied in order. For example, to skip arg3 and arg4, use the following command:

objRef->ObjMethod, arg1, arg2

Finding Object Methods


In most cases, when you incorporate a COM object into an IDL program, you will know what the COM object’s methods are and what arguments and data types those methods take, either because you created the COM object yourself or because the developer of the object provided you with the information.

If for some reason you do not know what methods the COM object supports, you may be able to determine which methods are available and what parameters they accept using the OLE/COM Object Viewer application provided by Microsoft.

Note: Finding information about a COM object’s methods using the OLE/COM Object
Viewer requires a moderately sophisticated understanding of COM programming, or at least COM interface definitions. While we provide some hints in this section on how to interpret the interface definition, if you are not already familiar with the structure of COM objects you may find this material inadequate. If possible, consult the developer of the COM object you wish to use rather than attempting to determine its structure using the object viewer.

Displaying Interface Information Using the Object Viewer

You can use the OLE/COM Object Viewer (supplied with Visual C++) to view the interface definitions for any COM object on your Windows machine. Select a COM object in the leftmost panel of the object viewer, click the right mouse button, and select View Type Information. A new window, ITypeLib Viewer will appear, showing all of the component’s interfaces:

Note: The top lines in the right-hand panel will say something like:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: RSIDemoComponent.dll
The “.IDL file” in this case has nothing to do with IDL, the Interactive Data Language. Here “IDL” stands for Interface Description Language, a language used to define component interfaces. If you are familiar with the Interface Description Language, you can often determine what a component is designed to do.

With the top-level object selected in the left-hand pane of the ITypelib Viewer, scroll down in the right-hand pane until you find the section that defines the IDispatch interface for the object in question. The definition will look something like this:

interface IRSIDemoObj1 : IDispatch
{
  [id(0x00000001)]
  HRESULT GetCLSID([out, retval] BSTR* pBstr);
  [id(0x00000002), propput]
  HRESULT MessageStr([in] BSTR pstr);
  [id(0x00000002), propget]
  HRESULT MessageStr([out, retval] BSTR* pstr);
  [id(0x00000003)]
  HRESULT DisplayMessageStr();
  [id(0x00000004)]
  HRESULT Msg2InParams(
  [in] BSTR str, [in] long val, [out, retval] BSTR* pVal);
  [id(0x00000005)]
  HRESULT GetIndexObject( [in] long ndxObj, [out, retval] IDispatch** ppDisp);
  [id(0x00000006)]
  HRESULT GetArrayOfObjects( [out] long* pObjCount, [out, retval] VARIANT* psaObjs);
};

Method definitions look like this:

[id(0x00000001)]
HRESULT GetCLSID([out, retval] BSTR* pBstr);

where the line including the id string is an identifier used by the object to refer to its methods and the following line or lines (usually beginning with HRESULT) define the method’s interface.

While it is beyond the scope of this Help to discuss COM object methods in detail, the following points may assist you in determining how to use a COM object:

  • Methods whose definitions include the retval attribute will appear in IDL as functions.
  • [id(0x00000001)]
    HRESULT GetCLSID([out, retval] BSTR* pBstr);
  • Methods that do not include the retval attribute will appear in IDL as procedures.
  • [id(0x00000003)] 
    HRESULT DisplayMessageStr();
  • Methods whose definitions include the propget attribute allow you to retrieve an object property using the IDLcomIDispatch::GetProperty method. You cannot call these methods directly in IDL; see Managing COM Object Properties for additional details.
  • [id(0x00000002), propget] 
    HRESULT MessageStr([out, retval] BSTR* pstr);
  • Methods whose definitions include the propput attribute allow you to set an object property using the IDLcomIDispatch::SetProperty method. You cannot call these methods directly in IDL; see Managing COM Object Properties for additional details.
  • [id(0x00000002), propput] 
    HRESULT MessageStr([in] BSTR pstr);
  • Methods that accept optional input values will include the optional token in the argument’s definition. For example, the following definition indicates that the second input argument is optional:
  • [id(0x00000004)] 
    HRESULT Msg1or2InParams( [in] BSTR str, [in, optional] int val, [out, retval] BSTR* pVal);
  • Methods that provide default values for optional arguments replace the optional token with the defaultvalue() token, where the default value of the argument is supplied between the parentheses. For example, the following definition indicates that the second input argument is optional, and has a default value of 15:
  • HRESULT Msg1or2InParams( [in] BSTR str, [in, defaultvalue(15)] int val, [out, retval] BSTR* pVal);
  • While methods generally return an HRESULT value, this is not a requirement.

Displaying Interface Information Using the IDL HELP Procedure

If you have an IDL program that instantiates a COM object running on your computer, you can determine either the class ID or the program ID by using the HELP command with the OBJECTS keyword. IDL displays a list of objects, along with their methods, with function and procedure methods in separate groups for each object class.