栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

COM组件基本概念

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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


                   else if(iid == IID_IX)


                            *ppv = static_cast(this);


                   else if(iid == IID_IY)


                            *ppv = static_cast(this);


                   else if(iid == IID_CA)


                            *ppv = static_cast(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"< 

所有的组件提供了相同的几个函数: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组件支持的接口,继而调用对应接口的函数。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1004879.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号