回忆一下COM技术5中我们创建组件的方法,客户以DLL的名称做为参数.装载此DLL并调用其中所输出的函数CreateInstance.这个函数可以建立一个组件的实例并给客户返回一个IUnknown接口的指针.但是组件对我们来说仍是不透明的,我们需要知道实现组件DLL的位置.但是COM组件实际上可以透明地在网络上(或本地)被重新分配位置,而不会影响本地客户程序.所以,由客户端来调用DLL并不是什么好主意.必须有一种更好的办法让组件的实现更透明,更灵活.于是就出现了类厂的概念.这和设计模式中封装变化点的思想一致,哪里有变化,我就封装哪里.类厂封装了组件的产生过程.下面来看看这一系列活动内部运转的详细过程:我在 http://www.cnblogs.com/shipfi/archive/2007/02/13/649196.html 里找到了详细介绍:
/**/
/*
1.实现二个接口IX,IY
2.实现一个组件CA,实现了IX,IY接口.
3.对于这个组件进行注册,把组件的信息加入到注册表中.实现DllRegisterServer和DllUnregisterServer函数.函数具体功能就是把本组件的CLSID,ProgID,DLL的位置放入注册表中.这样程序就可以通过查询注册表来获得组件的位置.
*/
/**/ /*
4.创建本组件类厂的实例
*/
class CFactory: public IClassFactory
... {
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv);
}
/**/ /*
在类厂实例中,主要的功能就是CreateInstance了,这个函数就是创建组件的相应实例.看它的实现:
*/
HRESULT __stdcall CFactory::CreateInstance(IUnknown * pUnknownOuter, const IID & iid, void ** ppv)
... {
//...
CA* pA = new CA;
if(pA == NULL)
...{
return E_OUTOFMEMORY;
}
HRESULT hr = pA->QueryInterface(iid,ppv);
pA->Release();
return hr;
}
/**/ /*
5.在这个组件的DLL中导出DllGetClassObject函数.这个函数的功能就是创建类厂的实例对象并查询接口.看其实现:
*/
STDAPI DllGetClassObject( const CLSID & clsid, const IID & iid, void ** ppv)
... {
//....
1.实现二个接口IX,IY
2.实现一个组件CA,实现了IX,IY接口.
3.对于这个组件进行注册,把组件的信息加入到注册表中.实现DllRegisterServer和DllUnregisterServer函数.函数具体功能就是把本组件的CLSID,ProgID,DLL的位置放入注册表中.这样程序就可以通过查询注册表来获得组件的位置.
*/
/**/ /*
4.创建本组件类厂的实例
*/
class CFactory: public IClassFactory
... {
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv);
}
/**/ /*
在类厂实例中,主要的功能就是CreateInstance了,这个函数就是创建组件的相应实例.看它的实现:
*/
HRESULT __stdcall CFactory::CreateInstance(IUnknown * pUnknownOuter, const IID & iid, void ** ppv)
... {
//...
CA* pA = new CA;
if(pA == NULL)
...{
return E_OUTOFMEMORY;
}
HRESULT hr = pA->QueryInterface(iid,ppv);
pA->Release();
return hr;
}
/**/ /*
5.在这个组件的DLL中导出DllGetClassObject函数.这个函数的功能就是创建类厂的实例对象并查询接口.看其实现:
*/
STDAPI DllGetClassObject( const CLSID & clsid, const IID & iid, void ** ppv)
... {
//....