Previous: , Up: Using COM objects with GNAT   [Contents][Index]


3.2 The Dynamic Method

Step 1 - Initialize COM

Initialize the COM libraries with a call to CoInitialize:

hr : Win32.Winerror.HRESULT;
hr := CoInitialize (System.Null_Address);

Step 2 - Get CLSID from PROGID

Retrieve the CLSID of the object using the Program ID (this may also be done for the static method) and the API call CLSIDFromProgID.

For example:

Class_ID : aliased CLSID;
Hr := CLSIDFromProgID
  (To_LPCOLESTR (To_C
   (Wide_String'("GNATCOMLibrary.GNATCOMClass"))'Address),
   Class_ID'Unchecked_Access);

Step 3 - Create Object

Create the object and request the IDispatch interface.

For Example:

hr := CoCreateInstance (Class_ID'Unchecked_Access,
                        null,
                        Win32.DWORD (CLSCTX_ALL),
                        IDispatch_ID'Unchecked_Access,
                        RetPointer'Unchecked_Access);
Dispatch_Ref := To_Pointer_To_Idispatch (RetPointer);

Step 4 - Look up ID and Invoke

Look up the dispatch IDs for methods and properties using the GetIDsOfNames method of IDispatch followed by calls to its invoke method.

For example:

declare
   Method_Name  : aliased Win32.ObjBase.LPOLESTR :=
     To_LPOLESTR (To_C (Wide_String'("Beep"))'Address);
   ID           : aliased Win32.OleAuto.DISPID;

   No_Arguments : aliased Win32.OleAuto.DISPPARAMS :=
     (null, null, 0, 0);
   Result       : aliased Win32.OleAuto.Variant;
   Excep_Info   : aliased Win32.OleAuto.EXCEPINFO;
   Arg_Err      : aliased Win32.UINT;
begin
   Put_Line ("Look up ID of method to call");

   Hr := Dispatch_Ref.lpvtbl.GetIDsOfNames
           (Dispatch_Ref,
            To_LPIID(System.Null_Address),
            Method_Name'Unchecked_Access,
            1,
            0,
            ID'Unchecked_Access);

   Hr := Dispatch_Ref.lpvtbl.Invoke (Dispatch_Ref,
                                     ID,
                                     To_LPIID (System.Null_Address),
                                     0,
                                     DISPATCH_METHOD,
                                     No_Arguments'Unchecked_Access,
                                     Result'Unchecked_Access,
                                     Excep_Info'Unchecked_Access,
                                     Arg_Err'Unchecked_Access);
end;

Step 5 - Release

When the interface is no longer needed a call to Release should be made.

For example:

refcount : Win32.ULONG;
refcount := Dispatch_Ref.lpvtbl.Release (Dispatch_Ref);

The reference count that is returned can be bogus and should not be relied upon for any purpose.

Step 6 - Unitialize COM

Shutdown the COM libraries with a call to CoUninitialize.

CoUninitialize;

The client code should be compiled with the linker option -lole32 and -loleaut32 to include the needed linker libraries. See the GNAT example com_dynamic.adb for a complete example of using COM objects dynamically.


Previous: , Up: Using COM objects with GNAT   [Contents][Index]