C++ static binding

C++ world depends on member functions to interface with external world. C++ compiler creates a compiler table to lookup the function needed for a class. This type of binding is called compile time binding or static binding. This is good when program is compiled along with static or dynamic library.

compile-time-binding

C++ dynamic binding

COM/DCOM C, C++ and C# language use vtable addresses to call COM/DCOM functions. Additional COM functions are placed after IUnknown vtable entries. Each function takes size of pointer and function can be called adding the offset in the vtable. This is the mechanism of C++ compiler to support inheritance and pure virtual functions.

dynamic-binding-vptr-vtable

DCOM ID binding

COM and DCOM works in different way. Here component interface definitions are distributed to user and component is distributed with software packages which are used by different programming languages other than C++. Languages like VB, JavaScripts, .NET etc. which are run time interpreted and they do not relay on vtable. This vtable runtime binding mechanism cannot work for scripting languages. IDispatch interface is used to support type info and additional functions. GetIDsOfNames can translate the function name to a numerical identity. This ID can be passed to Invoke call to call the actual function.

idispatch-id-binding-invoke-getidsofname

IDispatch::GetIDsOfNames

Maps a single member and an optional set of argument names to a corresponding set of integer DISPIDs, which can be used on subsequent calls to IDispatch::Invoke.

 
HRESULT GetIDsOfNames(  
  REFIID  riid,                  
  OLECHAR FAR* FAR*  rgszNames,  
  unsigned int  cNames,          
  LCID   lcid,                   
  DISPID FAR*  rgDispId          
);

Parameters

  • riid - Reserved and must be IID_NULL.
  • rgszNames - Passed-in array of names to be mapped.
  • cNames - Count of the names to be mapped. Count of items in rgszNames array.
  • lcid - The locale context in which to interpret the names.
  • rgDispId - Caller-allocated array, each element of which contains an identifier (ID) corresponding to one of the names passed in the rgszNames array. The first element represents the member name. The subsequent elements represent each of the member's parameters.

Return Value

The return value obtained from the returned HRESULT is one of the following:

  • S_OK - Success.
  • E_OUTOFMEMORY - Out of memory.
  • DISP_E_UNKNOWNNAME One or more of the names were not known. The returned array of DISPIDs contains DISPID_UNKNOWN for each entry that corresponds to an unknown name.
  • DISP_E_UNKNOWNLCID The locale identifier (LCID) was not recognized.

DISP IDs in IWebBrowser

This is the IDL definition of IWebBrowser in EXDISP.IDL. It shows DISP IDs of GoBack, GoForward,GoHome,GoSearch,Navigate methods and DISP ID of the property Visible.

[
  uuid(EAB22AC1-30C1-11CF-A7EB-0000C05BAE0B), /*IID_IWebBrowser*/
  helpstring("Web Browser interface"),
  helpcontext(0x0000),
  hidden,
  dual,
  oleautomation,
  odl
]
interface IWebBrowser : IDispatch 
{
  [id(100),
    helpstring("Navigates to the previous item in the history list."),
    helpcontext(0x0000)
  ]
  HRESULT GoBack();

  [id(101),
    helpstring("Navigates to the next item in the history list."),
    helpcontext(0x0000)
  ]
  HRESULT GoForward();

  [id(102),
    helpstring("Go home/start page."),
    helpcontext(0x0000)
  ]
  HRESULT GoHome();

  [id(103),
    helpstring("Go Search Page."),
    helpcontext(0x0000)
  ]
  HRESULT GoSearch();

  [id(104),
    helpstring("Navigates to a URL or file."),
    helpcontext(0x0000)
  ]
  HRESULT Navigate(
      [in] BSTR URL,
      [in, optional] VARIANT * Flags,
      [in, optional] VARIANT * TargetFrameName,
      [in, optional] VARIANT * PostData,
      [in, optional] VARIANT * Headers
  );
}

IWebBrowser DISP id demo

Below example code is a demo of GetIDsOfNames() call. It takes few method names of IWebBrowser and returns the DISP IDs of each methods.


#include <stdio.h>
#include <exdispid.h>      /* IE Events */
#include <objbase.h>      /* COM initialization */
#include <mshtml.h>        /* Internet Explorer IHTML Objects */
#include <mshtmcid.h>      /* Additional Internet Explorer Constants */
#include <mshtmhst.h>      /* Additional Internet Explorer Constants */
#include <exdisp.h>

int main(int argc, char* argv[])
{
  IDispatch *pBrowser;
  IUnknown *pUnknown;
  CLSID clsid;
  HRESULT hr;
  DISPID disp[6];
  LPOLESTR strMethods[] = {
    L"GoBack",
    L"GoForward",
    L"GoHome",
    L"GoSearch",
    L"Navigate",
    L"Visible"
  };

  CoInitialize(NULL);
  hr = CLSIDFromProgID(OLESTR("InternetExplorer.Application"), &clsid);
  if(hr != S_OK)
    return hr;

  hr = CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IUnknown, (LPVOID *) &pUnknown);
  if(hr != S_OK)
    return hr;

  hr = pUnknown->QueryInterface(IID_IWebBrowser, (LPVOID *) &pBrowser);
  if(hr != S_OK)
    return hr;

  wprintf(L"GetIDsOfNames demo with IWebBrowser interface\r\n");
  
  for(int i = 0; i< 6;i++){
    hr = pBrowser->GetIDsOfNames(IID_NULL,&strMethods[i], 1,LOCALE_SYSTEM_DEFAULT,&disp[i]);
    if(hr == S_OK) {
       wprintf(L"%s => id(%d)\r\n", strMethods[i],disp[i]);
    } else {
      wprintf(L"%s => Error %X\r\n", hr);
    }
  }
  pUnknown->Release();
  pBrowser->Release();
  CoUninitialize();
  return 0;
}

IWebBrowser DISP id output

GetIDsOfNames demo with IWebBrowser interface
GoBack => id(100)
GoForward => id(101)
GoHome => id(102)
GoSearch => id(103)
Navigate => id(104)
Visible => id(402)
Press any key to continue

About our authors: Team EQA

You have viewed 1 page out of 67. Your COM/DCOM learning is 0.00% complete. Login to check your learning progress.

#