分类: WINDOWS
2008-05-06 10:32:49
类厂是COM对象的生产基地,类厂本身也是一个COM对象,它支持一个特殊的接口:IClassFactory
class IClassFactory : public IUnknow
{
virtual HRESULT _stdcall CreateInstance(
IUnknow* pUnknownOuter, const IID& iid, void ** ppv) = 0;
virtual HRESULT _stdcall LockServer(BOOL bLock) = 0;
}
其中CreateInstance用于创建对应的COM对象,而LockServer用于控制组件的生存期。
类厂的实现:
class CSampleFactory : public IClassFactory
{
public:
……
//IUnknow members
HRESULT QueryInterface(const IID& iid, void **ppv);
ULONG AddRef();
ULONG Release();
//IClassFactory members
HRESULT CreateInstance( IUnknow* pUnknownOuter,
const IID& iid,
void **ppv);
HRESULT LockServer(BOOL);
}
类厂本身也是一个COM对象,类厂对象则是由DllGetClassObject引出函数来创建。
HRESULT DllGetClassObject(
const CLSID& clsid,
const IID& iid,
(void **)ppv );
DllGetClassObject又是在那儿被使用到呢?看下面 ^^
COM库与类厂的交互:一般来说,在COM库中CoGetClassObject、CoCreateInsance等函数用于创建类厂对象,并返回类厂接口指针。
ps:CoCreateInstance的内部实现也是调用了CoGetClassObject。
HRESULT CoGetClassObject(
const CLSID& clsid,
DWORD dwClsContext,
COSERVERINFO* pServerInfo, //Used for DCOM, now it should be NULL.
(void **)ppv
};
CoGetClassObject函数首先找到由clsid指定的COM类的类厂,调用DllGetClassObject创建类厂,并返回类厂对象接口指针。
想象一下CoGetClassObject的概要实现:
[
根据clsid得到dll所在的位置 — dllpath
typedef HRESULT (DllGetClsObj)(REFCLSID, REFIID, LPVOID*);
DllGetClsObj* pFun;
HINSTANCE hComponent = ::LoadLibrary(dllpath);
pFun = (DllGetClsObj*)::GetProcessAddRess(
hComponent,
"DllGetClassObject"
);
IClassFactory* pFactory;
HRESULT hr = (*pFun)(clsid, IID_IClassFactory, (void**)&pFactory);
……
]
DLLGetClassObject函数创建类厂.
想象一下DLLGetClassObject的概要实现:
[
CSampleFactory *pf = new CSampleFactory();
一般,我们需要得到类厂接口的指针~~~ 则
HRESULT hr = pf->QueryInterface(IID_IClassFactory, (void**)&pFactory);
……
]
这时,我们终于得到了类厂接口指针pFactory ,继续继续 ……
IUnknown* pUnknow;
hr = pFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnknow);
假设我们定义的接口为IMotion,需要返回的接口指针为pMot,则执行
hr = pUnknow->QueryInterface(IID_IMotion, (void**)&pMot);
好不容易,终于得到了所需要的接口指针了=_=!!!
为什么类厂的CreateInstance函数就能返回需要的接口指针呢?还得想象一下它的内部实现:
[
CSample* pObj = new CSample();
pObj->QueryInterface(iid, ppv);
……
]