Previous: The Static Method, 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: The Static Method, Up: Using COM objects with GNAT [Contents][Index]