Click here to Skip to main content
Licence 
First Posted 19 Nov 2001
Views 104,285
Bookmarked 22 times

Early-binding to a non-existent COM object

By | 20 Nov 2001 | Article
Simple code that early-binds to a COM object that has not been implemented yet

In my previous article "Getting the most out of IDispatch", I introduced a C++ class, XYDispDriver, which can be used to create any COM object (well, almost any) and call its methods. With this class, we no longer need a separate wrapper class for each type of COM object we want to use. For those of you who are familiar with the #import directive, we don't need that either (not that it is not useful).

To call a method in a COM object using XYDispDriver, we only need to know the parameter types and return type (although we can get this info dynamically). In other words, we need the COM interface, not the COM object itself. As I understand it, a COM interface is just a contract between the users and the implementer of the COM object. So there is nothing to prevent us from writing code that uses a COM object before the COM object is actually implemented, and you can do that easily with the help of XYDispDriver. Of course, you have to create a dummy COM object to test the code or wait until after the COM object is implemented to test.

As some readers have pointed out, XYDispDriver uses IDispatch::Invoke to call COM methods indirectly, which is called late-binding. Late-binding is not as efficient as early-binding, which calls the COM methods directly. If you have looked at the .tlh files generated by the #import directive, you will see that it uses both early-binding and late-binding. To do early-binding, at least as I thought previously, the COM object has to be implemented first. But I was wrong. If we already know the COM interface (the contract), early-binding is actually possible without the COM object being implemented.

I wrote the following console application that early-binds to a non-existent COM object. We assume that the prog id of the non-existent COM object is TestObj.1, the COM interface is derived from IDispatch, and there is only one method called Test which takes an input string parameter and an output string parameter. As you can see, it is very easy to do early-binding. Here is the code.

#include <stdio.h>
#include <oaidl.h>

// first define a com interface with the Testmethod
// (the order and signatures of methods have to be
// the same as in the future com object)
interface ITestObj : public
IDispatch
{
public:
    virtual HRESULT STDMETHODCALLTYPE Test(BSTR strInput, BSTR* pOutput) = 0;
};

// the main function that uses a non-existent com object
void main()
{
    // initialize com
    ::CoInitialize(NULL);
    // find the class id of the com object from its prog id
    CLSID clsidObj;
    HRESULT hRet = ::CLSIDFromProgID(L"TestObj.1", &clsidObj);
    if(hRet==S_OK)
    {
        // declare a pointer to the com interface
        ITestObj* pDisp = NULL;
        // create the com object
        hRet = ::CoCreateInstance(clsidObj,NULL,CLSCTX_ALL,IID_IDispatch,(void**)&pDisp);
        if(hRet==S_OK)
        {
           // declare input and output parameters
           BSTR strInput = ::SysAllocString(L"This is test 3");
           BSTR strOutput = NULL;
           // call the Test method (early-binding!!!)
           hRet = pDisp->Test(strInput,&strOutput);
           if(hRet==S_OK)
           {
               // print the output string
               wprintf(L"%s\n",strOutput);
               // free the output string
               ::SysFreeString(strOutput);
           }
           else printf("Error: %s",hRet);
           // free the input string
           ::SysFreeString(strInput);
           // release the com interface
           pDisp->Release();
        }
        else printf("Error: %x",hRet);
    }
    else printf("Error: %x",hRet);
    // uninitialize com
    ::CoUninitialize();
}

The above console app will compile fine without the actual COM object. Now you can use the ATL COM Wizard to generate a project for the COM object and implement the Test method as specified in the COM interface. After building the COM object, run the console app to verify that early-binding works! You can, of course, use the same technique for more complicated COM interfaces.

The code in this article is mainly for educational and entertainment purposes. You can find more code and articles from my home page. Thank you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Xiangyang Liu 刘向阳



United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalis com just dlls? PinmemberXarzu17:51 30 May '11  
GeneralDoes not work in general case PinmemberTimo Kettunen4:55 18 Aug '04  
GeneralRe: Does not work in general case PinmemberXiangyang Liu6:02 18 Aug '04  
GeneralGood way for calling plugins Pinmemberaxel6682:01 1 Sep '03  
GeneralRe: Good way for calling plugins PinmemberXiangyang Liu2:08 1 Sep '03  
QuestionCan the same technique be used to raise events? PinmemberErnesto Moscoso7:32 14 Aug '03  
GeneralThanks PinmemberMitesh H. Budhabhatti19:24 25 Jun '03  
Generalcomment of a file PinsussAnonymous16:05 17 Nov '02  
QuestionProblem? PinmemberTemplMetaProg10:44 3 Jul '02  
General#import PinmemberNishant Singh Kaur11:01 21 Nov '01  
GeneralRe: #import PinmemberXiangYangLiu11:30 21 Nov '01  
Generalnothing new for COM programmers PinmemberIUnknown9:28 21 Nov '01  
GeneralRe: nothing new for COM programmers PinmemberXiangYangLiu11:25 21 Nov '01  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 21 Nov 2001
Article Copyright 2001 by Xiangyang Liu 刘向阳
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid