Home Search Contact us About us
Title Using the simple CoCreateInstance function to instanciate a COM object.
Summary The CoCreateInstance function provides the most basic method of Instanciating a COM object. It is also capable of encouraging the object to be instanciated on a remote machine without to much trouble.
Contributor John McTainsh
Published 5-Feb-2001
Last updated 5-Feb-2001
Page rating   93% for 44 votes Useless Brilliant

Description.

Use this method to use a COM object with the same process, or a remove process. This method does not require smart pointers so it is up to the developer to do the right thing when done with the object so it will be released.

Where do the names come from?

The name of the items in this example can be found in the tlh file and class factory as follows;

Name here Purpose How to find
TrickyCom.dll Name of the file containing the object. May be a DLL or EXE. Path and name of file.
CLSID_CtrlFlasher Class ID for the object. Located at the end of .tlh. Only created if the import directive includes named_guids
TRICKYCOMLib This is the Library name space The namespace is located in .tlh and begins with namespace and ends with ...Lib {
ICtrlFlasherPtr Smart pointer name Look in .tlh and add Ptr to the end of the first parameter in _COM_SMARTPTR_TYPEDEF(ICtrlFlasher,
CtrlFlasher The coclass name Look in .tlh and use the name defines in struct /* coclass */ CtrlFlasher;
Increment() and Count The methods and properties Look in .tlh for the // Property data and // Wrapper methods for error-handling sections

Solution using the object throughout a class.

At the top of the file or in StdAfx.h add. Note the named_guids flag is very important.

#import "..\Debug\TrickyCom.exe" named_guids
using namespace TRICKYCOMLib;

In Gizzmo.cpp in BOOL CGizzmoApp::InitInstance(); or any simular start-up function that is called only once.

    //Initialise the application for use with COM objects
    HRESULT hr = CoInitialize( NULL );
    if( FAILED( hr ) )
    {
        AfxMessageBox( "CoInitialize failed\n");
        return FALSE;
    }

    //TODO Call CoUninitialize(); in the Destructor or other location
    //when all COM activity is completed.

In the header of the class place the object reference variable. UseItHere.h

    ICtrlFlash* m_pFlash;                 //Interface pointer

In class contructor initialise the variable. UseItHere.cpp Constructor.

    m_pFlash = NULL;

In class destructor release the object. UseItHere.cpp Destructor.

    m_pFlash->Release();
    m_pFlash = NULL;

In an initialisation routine such as InitDialog instantiate the object. UseItHere.cpp.

    try
    {
        HRESULT hr;

        //
        //Create the COM object
        //
        hr = CoCreateInstance( CLSID_CtrlFlash, 0, CLSCTX_ALL, IID_ICtrlFlash, (void**)&m_pFlash );
        if( FAILED(hr) )
            _com_issue_error(hr);

    }
    catch( _com_error e )
    {
        TRACE( _T("COM - Error %08x : %s\n"), e.Error(), e.ErrorMessage() );
    }

Place this code where you want to access the object. ie In a button handler.

    try
    {
        TRACE( _T("Inital count = %d\n"), pFlash->nBeerCount );
        pFlash->MoreBeer();
    }
    catch( _com_error e )
    {
        //Catch and display errors
        TRACE( _T("Com Error %x, %s\n"), e.Error, e.ErrorMessage() );
    }

All in one function

Here is another example doing every thing in the one function.

    //Initialise the application for use with COM objects
    HRESULT hr = CoInitialize( NULL );
    if( FAILED( hr ) )
    {
        printf( "CoInitialize failed\n" );
        return FALSE;
    }
    
    //Requires #import "..\..\Set01\Debug\Set01.dll" named_guids
    IWhereAmI* pWAI = NULL;
    try
    {      
        hr = CoCreateInstance( CLSID_WhereAmI, 0, CLSCTX_ALL, IID_IWhereAmI, (void**)&pWAI );
        if( FAILED( hr ) )
            _com_issue_error(hr);

        //Get the object version info
        printf( "Inital count = %d\n", pWAI->BuildNo );

        //Get the machine name
        BSTR bstrMachineName;
        hr = pWAI->GetMachine( &bstrMachineName );
        if( FAILED( hr ) )
            _com_issue_error(hr);
        wprintf( L"Where is it  = %s\n", bstrMachineName );
        SysFreeString( bstrMachineName );
    }
    catch( _com_error e )
    {
        //Catch and display errors
        printf( "Com Error %x, %s\n", e.Error, e.ErrorMessage() );
    }           

    //Free up when we are done
    if( pWAI != NULL )
        pWAI->Release();

    //We are done with COM
    CoUninitialize();

Note, this object may be instanciated out of process or on a remote machine by using a Surrogate. The Surrogate apears in the process list as DLLHOST.EXE.

  • Open "OLE/COM Viewer".
  • Expand the "All Objects" branch.
  • Click on the object you want to Surrogate.
  • Check the "Use Surrogate Process" on the Implementation Property page.
  • Modify CoCreateInstance(, replace CLSCTX_ALL with CLSCTX_LOCAL_SERVER.
  • This will result in a more robust object but will signifigantly reduce performance.
  • If you want remote instanciate on another machine.
    • Modify CoCreateInstance(, replace CLSCTX_ALL with CLSCTX_REMOTE_SERVER.
    • In "OLE/COM Viewer" select the Activation Tab.
    • Set the Remote Machine Name to the computer you want the object to be instanciated on.
    • The object dll must be registered on that computer and set to run a a Surrogate.
    • Under these conditions security is enabled by default so it may be nessary to se some permissions.
Comments Date
Home Search Contact us About us