Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. How do I determine if a certain method exists on an interface?

How do I determine if a certain method exists on an interface?

Scheduled Pinned Locked Moved COM
c++questioncomannouncement
6 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gary Chapman
    wrote on last edited by
    #1

    I have a COM DLL written in C++/ATL. I added a new method to one of the interfaces and altered my testbed to call this new method. I then went and registered an earlier version of the DLL which doesn't contain the new method. Not surprisingly, an exception is raised when the testbed tries to call the method. I can catch this with a try/catch handler, but I still get an unrecoverable exception when the calling function exits (see code snippet below). Is there anyway of interrogating the interface to see if the method exists? If not, is there I way my app can continue to run gracefully? This final 0xC0000005 exception is a bit of a showstopper. Thanks, Gary --- void func() { ::CoInitialize(NULL); try { CComPtr MyInt; MyInt.CoCreateInstance(CLSID_MyInterface); MyInt->NewMethod(); } catch(...) { AfxMessageBox("eek"); } } // exception 0xC0000005 thrown here

    X 1 Reply Last reply
    0
    • G Gary Chapman

      I have a COM DLL written in C++/ATL. I added a new method to one of the interfaces and altered my testbed to call this new method. I then went and registered an earlier version of the DLL which doesn't contain the new method. Not surprisingly, an exception is raised when the testbed tries to call the method. I can catch this with a try/catch handler, but I still get an unrecoverable exception when the calling function exits (see code snippet below). Is there anyway of interrogating the interface to see if the method exists? If not, is there I way my app can continue to run gracefully? This final 0xC0000005 exception is a bit of a showstopper. Thanks, Gary --- void func() { ::CoInitialize(NULL); try { CComPtr MyInt; MyInt.CoCreateInstance(CLSID_MyInterface); MyInt->NewMethod(); } catch(...) { AfxMessageBox("eek"); } } // exception 0xC0000005 thrown here

      X Offline
      X Offline
      Xiangyang Liu
      wrote on last edited by
      #2

      Gary Chapman wrote: Is there anyway of interrogating the interface to see if the method exists? You need to call GetIDsOfNames after CoCreateInstance to determine if a method exists on a given interface. The way your code is written will not work because even if the method exists, you cannot call it as if it is early-bound (you are doing late-binding). What you need to call is the Invoke method of IDispatch. [Edit] As Bo Hunter pointed out, I was wrong in saying the code won't work. [/Edit] COM programming is very complicated without help from libraries like ATL or MFC. However, you can reuse some of my code[^] to save a lot of time. ;)[

      My articles and software tools

      ](http://hometown.aol.com/XiangYangL/)

      B V 2 Replies Last reply
      0
      • X Xiangyang Liu

        Gary Chapman wrote: Is there anyway of interrogating the interface to see if the method exists? You need to call GetIDsOfNames after CoCreateInstance to determine if a method exists on a given interface. The way your code is written will not work because even if the method exists, you cannot call it as if it is early-bound (you are doing late-binding). What you need to call is the Invoke method of IDispatch. [Edit] As Bo Hunter pointed out, I was wrong in saying the code won't work. [/Edit] COM programming is very complicated without help from libraries like ATL or MFC. However, you can reuse some of my code[^] to save a lot of time. ;)[

        My articles and software tools

        ](http://hometown.aol.com/XiangYangL/)

        B Offline
        B Offline
        Bo Hunter
        wrote on last edited by
        #3

        The interface would have to implement IDispatch would'nt it? If CLSID_Myinterface is a valid coclass then this code should work. This is perfectly valid code here.BOOL OpenLinkUsingCom(TCHAR* pLink, int how, HWND hWnd) { IUniformResourceLocator* pLocator; HRESULT hr = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (LPVOID*)&pLocator); if (SUCCEEDED(hr)) { hr = pLocator->SetURL(pLink, IURL_SETURL_FL_GUESS_PROTOCOL); if (SUCCEEDED(hr)) { URLINVOKECOMMANDINFO ivci; ivci.dwcbSize = sizeof(URLINVOKECOMMANDINFO); ivci.dwFlags = 0; ivci.hwndParent = hWnd; switch (how) { case OPEN: ivci.pcszVerb = _T("open"); break; case EDIT: ivci.pcszVerb = _T("edit"); break; case PRINT: ivci.pcszVerb = _T("print"); break; default: ATLASSERT(0); } hr = pLocator->InvokeCommand(&ivci); } } if (pLocator) pLocator->Release(); return (SUCCEEDED(hr)); }
        Please tell me if I am wrong. Thank You Bo Hunter

        X 1 Reply Last reply
        0
        • B Bo Hunter

          The interface would have to implement IDispatch would'nt it? If CLSID_Myinterface is a valid coclass then this code should work. This is perfectly valid code here.BOOL OpenLinkUsingCom(TCHAR* pLink, int how, HWND hWnd) { IUniformResourceLocator* pLocator; HRESULT hr = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (LPVOID*)&pLocator); if (SUCCEEDED(hr)) { hr = pLocator->SetURL(pLink, IURL_SETURL_FL_GUESS_PROTOCOL); if (SUCCEEDED(hr)) { URLINVOKECOMMANDINFO ivci; ivci.dwcbSize = sizeof(URLINVOKECOMMANDINFO); ivci.dwFlags = 0; ivci.hwndParent = hWnd; switch (how) { case OPEN: ivci.pcszVerb = _T("open"); break; case EDIT: ivci.pcszVerb = _T("edit"); break; case PRINT: ivci.pcszVerb = _T("print"); break; default: ATLASSERT(0); } hr = pLocator->InvokeCommand(&ivci); } } if (pLocator) pLocator->Release(); return (SUCCEEDED(hr)); }
          Please tell me if I am wrong. Thank You Bo Hunter

          X Offline
          X Offline
          Xiangyang Liu
          wrote on last edited by
          #4

          Bo Hunter wrote: Please tell me if I am wrong. Thank You Bo Hunter Sorry, I was wrong. You are right. :-O[

          My articles and software tools

          ](http://hometown.aol.com/XiangYangL/)

          1 Reply Last reply
          0
          • X Xiangyang Liu

            Gary Chapman wrote: Is there anyway of interrogating the interface to see if the method exists? You need to call GetIDsOfNames after CoCreateInstance to determine if a method exists on a given interface. The way your code is written will not work because even if the method exists, you cannot call it as if it is early-bound (you are doing late-binding). What you need to call is the Invoke method of IDispatch. [Edit] As Bo Hunter pointed out, I was wrong in saying the code won't work. [/Edit] COM programming is very complicated without help from libraries like ATL or MFC. However, you can reuse some of my code[^] to save a lot of time. ;)[

            My articles and software tools

            ](http://hometown.aol.com/XiangYangL/)

            V Offline
            V Offline
            Vi2
            wrote on last edited by
            #5

            If interface being tested is derived from IDispatch, the GetIDsOfNames is a simplest way to see it. The second way is the ITypeInfo::GetIDsOfNames for non-dual interface if the Type Library is accessible (either by LoadRegTypeLib or by LoadTypeLib). PS It is a bad practice to change the contents of interface without the changing of its IID. With best wishes, Vita

            B 1 Reply Last reply
            0
            • V Vi2

              If interface being tested is derived from IDispatch, the GetIDsOfNames is a simplest way to see it. The second way is the ITypeInfo::GetIDsOfNames for non-dual interface if the Type Library is accessible (either by LoadRegTypeLib or by LoadTypeLib). PS It is a bad practice to change the contents of interface without the changing of its IID. With best wishes, Vita

              B Offline
              B Offline
              Bo Hunter
              wrote on last edited by
              #6

              If the interface had already been published then yes you should give it a new name but for testing I don't think that is really relevent. Thank You Bo Hunter

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups