from
http://progtutorials.tripod.com/COM.htm
- Accessing DLL and EXE Servers using Class Factories
- Accessing Server with CoCreateInstance
- Execution Context
1 Accessing DLL and EXE Servers using Class Factories
There are two steps to access a server (DLL server or EXE server alike) through class factories:
- Client calls CoGetClassObject providing the REFCLSID of the coclass, which searches the System Registry, loads up the server if it is not yet loaded, calls the server's exported function DllGetClassObject, which returns its IClassFactory pointer;
- Client calls IClassFactory::CreateInstance with the REFIID of an interface of the coclass, which returns the interface pointer;
COM library API function CoGetClassObject calls the COM server¡¯s DllGetClassObject to acquire a class factory reference:
HRESULT CoGetClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
COSERVERINFO * pServerInfo,
REFIID riid,
LPVOID * ppv); COSERVERINFO is a structure to carry information for remote servers, which should be NULL if you are invoking in-proc or local servers.
Then you can acquire from the IClassFactory interface the interface you want.
Example:
Use AppWizard's option "Win32 Console Application" and "Empty Project" to create a totally empty project. Insert the iid.cpp file into the project, and put the following lines into the global file "ProjectName.cpp":
#include "..\cardll\interfaces.h"
#include "..\cardll\iid.h"
#include <iostream.h>
// Note: interface definition "interface.h" should be included prior to
// GUID definition "iid.h"
void main(int argc, char* argv[])
{
CoInitialize(NULL);
IClassFactory * pClassFactory = NULL;
HRESULT hr = CoGetClassObject(
CLSID_Car,
CLSCTX_SERVER,
NULL,
IID_IClassFactory,
(void **) &pClassFactory);
if(FAILED(hr)) // in the following code this error checking is omitted
{
cout << "CoGetClassObject failed!\n";
return;
}
IRegistration * pRegist = NULL;
hr = pClassFactory->CreateInstance(
NULL,
IID_IRegistration,
(void **) &pRegist);
BSTR bstr = SysAllocString(L"Frank Liu");
hr = pRegist->SetOwner(bstr);
SysFreeString(bstr);
hr = pRegist->GetOwner(&bstr);
char buf[80];
wcstombs(buf, bstr, 80);
cout << "Owner of the car is: " << buf << endl;
IStatus * pStatus = NULL;
pRegist->QueryInterface(IID_IStatus, (void **)&pStatus);
hr = pStatus->SetSpeed(120);
int nSpeed;
hr = pStatus->GetSpeed(&nSpeed);
cout << "Speed of the car is now " << nSpeed << endl;
return;
}
2 Accessing Server with CoCreateInstance
COM library API function CoCreateInstance wraps the two function calls ? CoGetClassObject and IClassFactory::CreateInterface:
#include "stdafx.h"
// The following two header files are generated by MIDL compiler.
// Alternatively, you can import the type library as instructed in
// Chapter IDL.
#include "..\test\test.h"
#include "..\test\test_i.c"
int main(int argc, char* argv[])
{
CoInitialize(NULL);
IAny * pAny = NULL;
HRESULT hr = CoCreateInstance(
CLSID_Any,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAny,
(void **)&pAny);
if(FAILED(hr))
printf("CoCreateInstance failed!");
hr = pAny->Hi();
pAny->Release();
return 0;
}
3 Execution Context
There are four execution contexts you can use when calling CoCreateInstance or CoCreateInstanceEx:
- CLSCTX_INPROC_SERVER
- CLSCTX_INPROC_HANDLER
- CLSCTX_LOCAL_SERVER
- CLSCTX_REMOTE_SERVER
CLSCTX_SERVER is an OR of the three server contexts.
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)