|
|
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 |
|
|
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.
|