COM组件基本概念

ActiveX的前身是MFC OLE,而后发展出来COM组件模型,COM组件模型是一个windows的动态运行组件标准。ActiveX控件是MFC对于COM组件标准的具体实现,以下简要介绍下COM组件模型。

COM组件本质上是一个动态链接库,组件中实现了不同功能的函数,这些函数可以划分为不同的函数集,每个函数集都是对一个纯虚基类的实现,该纯虚基类称为接口,最基本的一个纯虚基类如下所示:

//interface IUnknown


struct IUnknown{


    virtual HRESULT  QueryInterface(cosnt IID& iid, void ** ppv) = 0;


         virtual ULONG AddRef() = 0;


         virtual ULONG Release() = 0;


};

HRESULT是一个32 bit的整数,每一个位表示相应的状态,IID是统一资源标识符UUID,128 bit的常数,用于在注册表中唯一标识一个资源,如函数、程序、类名等。QueryInterface函数用于查询某个组件是否支持某个iid标识的接口,如果支持该函数集,那么QueryInterface在ppv中返回该接口的指针。AddRef函数用于增加引用计数。Release函数用于减少引用计数,当引用计数为0时,组件进行自我销毁。

所有其他的接口都继承IUnknown,例如:

//interface IX, assume iid is IID_IX


struct IX :public IUnknown{


         virtual void Fx()=0;


};




//interface IY, assume iid is IID_IY


struct IY:public IUnknown{


         virtual void Fy() = 0;


};


一个具体的组件例子如下:

//componenet CA, assume iid is IID_CA


IUnknown* CreateInstance()


{


         IUnknown* p = new CA;


         p->AddRef();


         return p;


}




class CA:public IX, public IY{


public:


         HRESULT QueryInterface(const IID& iid, void** ppv)


         {


                   if(iid == IID_IUnknown)


                            *ppv = static_cast<IX*>(this);


                   else if(iid == IID_IX)


                            *ppv = static_cast<IX*>(this);


                   else if(iid == IID_IY)


                            *ppv = static_cast<IY*>(this);


                   else if(iid == IID_CA)


                            *ppv = static_cast<CA*>(this);


                   else


                            {


                                     *ppv = NULL;


                                     return E_NOINTERFACE;


                            }


                   AddRef();


                   return S_OK;


         }


       


         ULONG AddRef()


         {


                   return ++m_refc;


         }


       


         ULONG Release()


         {


                   if(0 == --m_refc)


                            delete this;


                   return m_refc;


         }


       


         void Fx(){::std::cout<< "fx"<<endl;}


         void Fy(){::std::cout<< "fy" << endl;}


       


private:


         ULONG m_refc;


public:


         CA():m_refc(0){}


         ~CA(){}


};

所有的组件提供了相同的几个函数:CreateInstance、QueryInterface、AddRef、Release,所有使用COM组件的程序都可以使用这些函数,并且可以通过QueryInterface查询组件支持的接口,从而使用对应接口中的函数功能。

接口的声明文件interface.h(用于在客户程序和组件之间共享接口信息)

IUnknown* CreateInstance();




struct IUnknown{


    virtual HRESULT  QueryInterface(cosnt IID& iid, void ** ppv) = 0;


         virtual ULONG AddRef() = 0;


         virtual ULONG Release() = 0;


};




//interface IX, assume iid is IID_IX


struct IX :public IUnknown{


         virtual void Fx()=0;


};




//interface IY, assume iid is IID_IY


struct IY:public IUnknown{


         virtual void Fy() = 0;


};


extern const IID IID_IUnknown;


extern const IID IID_X;


extern const IID IID_Y;//(IID是一个128bit的数据结构,定义独一无二的接口ID)

一个使用组件的程序如下:

int main()


{


         ::std::cout << "main" << endl;


         IUnknown* pKnown = CreateInstance();


         IX* pIx = NULL;


         IY* pIy = NULL;


         pKnown->QueryInterface(IID_IX,pIx);


         pIx->Fx();


         pIx->Release();


         pKnown->QueryInterface(IID_IY,pIy);


         pIy->Fy();


         pIy->Release();


         pKnown->Release();


}

在实际运行中,com组件被编译成动态链接库,客户程序在使用com组件时加载该动态链接库,调用QueryInterface函数确定com组件支持的接口,继而调用对应接口的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值