Chinaunix首页 | 论坛 | 博客
  • 博客访问: 384579
  • 博文数量: 35
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 797
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-02 08:51
文章分类

全部博文(35)

文章存档

2011年(1)

2010年(3)

2009年(3)

2008年(28)

我的朋友

分类: 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库中CoGetClassObjectCoCreateInsance等函数用于创建类厂对象,并返回类厂接口指针。

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);

    ……

]

阅读(1402) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~