1 流程图
注: COM库指的是 OLE32.dll
2 COM创建函数
COM库中有三个用于创建组件的函数:
- CoGetClassObject
- CoCreateInstance
-
(1) CoGetClassObject
创建一个类厂, 并获取类厂指针作为输出参数
如果客户希望获取类厂对象或者要调用类厂的某些成员函数,则选用CoGetClassObject函数;HRESULT CoGetClassObject(
const CLSID& clsid,
DWORD dwClsContext,
COSERVERINFO *pServerInfo,
const IID& iid,
(void **)ppv
);
(2) CoCreateInstance
此函数内部调用了 CoGetClassObject 和 CreateInstance
在其他情况下,使用CoCreateInstance函数创建对象,这是最常用的方法HRESULT CoCreateInstance(
const CLSID& clsid,
IUnknown *pUnknownOuter,
DWORD dwClsContext,
const IID& iid,
(void **)ppv
);
实现伪码如下
HRESULT CoCreateInstance(const CLSID& clsid, IUnknown *pUnknownOuter,
DWORD dwClsContext, const IID& iid, void *ppv)
{
IClassFactory *pCF;
HRESULT hr;
hr = CoGetClassObject(clsid, dwClsContext, NULL, IID_IClassFactory, (void *)pCF);
if (FAILED(hr))
return hr;
hr = pCF->CreateInstance(pUnkOuter, iid, (void *)ppv);
pCF->Release();
return hr;
}
(3) CoCreateInstanceEx
如果客户创建远程对象或者希望一次获取对象的多个接口指针,则选用CoCreateInstanceEx函数;
HRESULT CoCreateInstanceEx(
const CLSID& clsid,
IUnknown *pUnknownOuter,
DWORD dwClsContext,
COSERVERINFO *pServerInfo,
DWORD dwCount,
MULTI_QI *rgMultiQI
);
3 类厂的实现
```cpp class CDictionaryFactory : public IClassFactory { protected:
ULONG m_Ref;
public:
CDictionaryFactory (void);
~ CDictionaryFactory (void);
//IUnknown members
HRESULT QueryInterface(const IID& iid, void **ppv);
ULONG AddRef();
ULONG Release();
//IClassFactory members
HRESULT CreateInstance(IUnknown *, const IID& iid, void **ppv);
HRESULT LockServer(BOOL);
};
HRESULT CDictionaryFactory::CreateInstance(IUnknown pUnknownOuter, const IID& iid, void **ppv)
{
CDictionary pObj;
HRESULT hr;
*ppv=NULL;
hr=E_OUTOFMEMORY;
if (pUnknownOuter != NULL)
return CLASS_E_NOAGGREGATION;
pObj=new CDictionary();
if (pObj== NULL)
return hr;
//Obtain the first interface pointer (which does an AddRef)
hr=pObj->QueryInterface(iid, ppv);
if (hr != S_OK) {
g_DictionaryNumber --;
delete pObj;
}
return hr;
}
extern “C” HRESULT __stdcall DllGetClassObject(const CLSID& clsid, const IID& iid, void *ppv) { if (clsid == CLSID_Dictionary ) { CDictionaryFactory pFactory = new CDictionaryFactory;
if (pFactory == NULL) {
return E_OUTOFMEMORY ;
}
HRESULT result = pFactory->QueryInterface(iid, ppv);
return result;
} else {
return CLASS_E_CLASSNOTAVAILABLE;
}
} ```