COM读书笔记之----类厂
昨天已确知创建组件可以用COM库中的CoCreateInstance函数来创建某个接口的指针,但是该函数的灵活性不高,于是,提出了类厂的方法,类厂即是用来创建组件的组件。
关于CoGetClassObject函数:
此函数我不知道与类厂有什么关联,但作者介绍类厂时,第一个着重介绍的就是此函数,此函数原型是这样的:
STDAPI CoGetClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
COSERVERINFO * pServerInfo,
REFIID riid,
LPVOID * ppv
);
看看与CoCreateInstance函数有什么不同,CoCreateInstance函数原型:
STDAPI CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv
);
最大不同的地方就是函数的参数,一个需要的是IUnknown的指针作参数。一个需要的是COSERVERINFO的指针作参数。书上提到,CoCreateInstance函数返回的则是指向组件中某个接口的指针,CoGetClassObject函数返回的则是类厂中某个接口的指针。最大的区别就是返回的指针所指向的接口不同!
类厂所支持用于创建组件的标准接口是IClassFactory,大多数组件均可使用IClassFactory接口来创建。它的接口声明如下:
interface TClassFactory : IUnknown
{
HRESULT stdcall;
CreateInstance(IUnknown** pUnknownOuter,
const IID &iid, void** ppv);
HRESULT __stdcall LockServer(BOOL block);
}
HRESULT CoCreateInstance(REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext, REFIID riid, LPVOID * ppv)
{
*ppv=NULL; //Set Pointer to NULL;
//Create the class factory and
//get an IClassFactory interface pointer
IClassFactory* pIFactory = NULL;
HRESULT hr = CoGetClassObject(rclsid,dwClsContext,
NULL,IID_IClassFactory,(void**)&pIFactory);
if(SUCCEEDED(hr))
{
//Create the Component
hr=pIFactory->CreateInstance(pUnkOuter,iid,ppv);
//Release the class factory
pIFactory->Release();
}
return hr;
}
什么时候该用CoGetClassObject函数:
一,若想用不同于IClassFactory的某个创建接口来创建组件,必须使用CoGetClassObject。比如想用IClassFactory2来创建组件,因为CoCreateInstance里面是用得IClassFactory创建接口来创建的,所以肯定不行。
二,若需要创建一个组件的多个实例,则可以用CoGetClassObject来获得更高的效率,因为这样只需创建类厂一次,而CoCreateInstance则需为每个实例分配相应的类厂。
记住:类厂只不过是创建其它组件的一个简单组件。
关于CoGetClassObject函数:
此函数我不知道与类厂有什么关联,但作者介绍类厂时,第一个着重介绍的就是此函数,此函数原型是这样的:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
看看与CoCreateInstance函数有什么不同,CoCreateInstance函数原型:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
最大不同的地方就是函数的参数,一个需要的是IUnknown的指针作参数。一个需要的是COSERVERINFO的指针作参数。书上提到,CoCreateInstance函数返回的则是指向组件中某个接口的指针,CoGetClassObject函数返回的则是类厂中某个接口的指针。最大的区别就是返回的指针所指向的接口不同!
类厂所支持用于创建组件的标准接口是IClassFactory,大多数组件均可使用IClassFactory接口来创建。它的接口声明如下:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
可以从该接口的声明中看到,得到IClassFactory接口指针后,就是调用IClassFactory接口中的CreateInstance来获得某个接口的指针,以创建相应的组件。第一个参数pUnknownOuter同传给CoCreateInstance函数的IUnknown指针是相同的,用于聚合组件(聚合还不了解,没讲到,不用管它)。其余的参数均和传给QueryInterface的参数相同。
CoCreateInstance与CoGetClassObject的联系:
其实,CoCreateInstance比CoGetClassObject要简单一些,CoCreateInstance函数也是调用CoGetClassObject来实现的。代码如下所示:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
什么时候该用CoGetClassObject函数:
一,若想用不同于IClassFactory的某个创建接口来创建组件,必须使用CoGetClassObject。比如想用IClassFactory2来创建组件,因为CoCreateInstance里面是用得IClassFactory创建接口来创建的,所以肯定不行。
二,若需要创建一个组件的多个实例,则可以用CoGetClassObject来获得更高的效率,因为这样只需创建类厂一次,而CoCreateInstance则需为每个实例分配相应的类厂。
记住:类厂只不过是创建其它组件的一个简单组件。