组件的设计与实现


Com组件从OLE技术上发展而来:

Object Linking and Embedding,对象连接与嵌入,简称OLE技术。OLE 不仅是桌面应用程序集成,而且还定义和实现了一种允许应用程序作为软件“对象”(数据集合和操作数据的函数)彼此进行“连接”的机制,这种连接机制和协议称为组件对象模型(COM)。

COM是一种规范而不是实现,是一种面向对象的编程标准(Component ObjectModule)在c++中COM实际就为c++类,用它来实现接口进行操作。

COM对于编程语言的唯一要求是必须能够创建结构指针,并可以通过指针调用函数。COM对象通过一组或多组相关函数来访问对象中的数据,这些数据集合称为接口。

接口是一个纯虚函数的定义,不能直接创建实体,每个接口都有一个全局唯一的GUID值,可以通过这个值访问接口。

所有的接口都是从一个核心接口IUnknown派生而来,IUnknown接口包含了三个重要的方法:QueryInterface、AddRef、Release。

QueryInterface用于说明这个组件是否支持特定接口,如果支持返回接口的指针,不支持返回一个空指针。

AddRef和Release实现对COM的内存引用 的计数。当对COM第一个调用AddRef时,COM被调入内存;当调用Release,最后释放COM时,COM会从内存释放。

COM组件在使用前应该进行注册,它的一些信息随着COM组件的注册被写入到注册表中,反注册就是把组件的注册信息从注册表中删除。Windows系统中使用 RegSvr32.exe对COM组件进行注册和反注册,RegSvr32.exe调用COM组件的DllRegisterServer注册,调用DllUnRegisterServer进行反注册。如com.dll为一个组件,则控制台注册:

RegSvr32 com.dll

反注册:

RegSvr32 –ucom.dll

 

COM组件的规则:

1、 实现IUnknown规则。Com组件必须实现IUnknown接口。

2、 内存管理规则。管理内存即管理指针,接口指针的寿命管理通过调用每个com接口中的AddRef()和Release()两种方法来实现。

3、 引用计数规则。 引用程序通过计数跟踪COM实例,保证符合COM规范。

 

Com组件的设计

VS中使用ATL方便设计组件。

ATL,Active Template Library活动模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。通过活动模板库,可以建立COM组件,然后通过ASP页面中的脚本对COM对象进行调用。这种COM组件可以包含属性页、对话框等等控件。

 

COM组件的调用之 工厂化方法调用接口

工厂化函数

STDAPI  CoGetClassObject

(

       REFCLSIDrclsid,  //组件的CLSID值

       WORDdwClsContext, //组件类别

       COSERVERINFO*pServerInfo, //服务器信息,默认为NULL

       REFIIDriid, //工厂方法标识符

       LPVOID*ppv, //COM组件工厂指针

)

调用了CoGetClassObject之后得到了IClassFactory接口指针,使用IClassFactory接口调用CreateInstance得到调用的指针接口。

HRESULT CreateInstance

(      IUnknown*pUnkOuter, //指向UnKnown接口,与CoCreateInstance相同

       REFIIDriid, //调用接口标识符

       Void** ppvObject  //接口指针

)

示例:

myCom组件含有IGetRes接口,该接口含有Hello()方法,IGetResEx接口,该接口还含有HelloEx()方法,使用工厂化方法调用COM接口方法。

CoInitialize(NULL);

HRESULT hr;

CLSID clsid;

//得到myCom组件IGetRes接口指针的CLSID号

hr = CLSIDFromProgID(OLESTR(“myCom.GetRes”),&clsid);

//首先说明i一个IGetRes接口、IGetResEx接口和类工厂接口

IGetRes* ptr;

IGetResEx* ptrEx;

IClassFactory* p_Classfactory;

//首先需要得到COM 对象工厂(IClassFactory)指针

hr = GoGetClassObject(clsid, CLSCTX_INPROC_SERVER,NULL, IID_IClassFactory, (LPVOID*) &p_Classfactory);

//使用工厂化的方法得到IGetRes接口指针

P_classfactory->CreateInstance(NULL,__uuidof(IGetRes), (LPVOID*) &ptr);

//使用工厂化的方法得到IGetResEx接口指针

P_Classfactory->CreateInstance(NULL,__uuidof(IGetResEx), (LPVOID*)&ptrEX);

//调用IGetRes接口的Hello函数

Ptr->Hello();

//调用IGetResEx接口的HelloEx()函数

ptrEx->HelloEx();

CoUninitialize();

 

 

Com组件使用API调用接口函数

STDAPI CoCreateInstance

(  REFCLSID rclsid,  //组件的CLSID值

       LPUNKNOWNpUnkOuter, //指向UnKnown接口

       DWORDdwClsContext, //组件类别

       REFIIDriid, //调用接口标识符

       LPVOID*ppv, //接口指针

)

pUnkOuter 如果为NULL, 表明此对象不是聚合式对象的一部分。如果不是NULL,则指针指向一个聚合式对象的IUnKnown接口

dwClsContext 参数一般设置为CLSCTX_INPROC_SERVER

riid 是接口的GUID值,可以通过以下函数得到:

__uuidof(expression)

uuidof 得到指向expression的GUID值。

使用API 调用接口IGetRes的方法Hello()的实例:

CoInitialize(NULL);

CLSID clsid;

//得到myCom组件IGetRes接口指针的CLSID号

HRESULT hr = CLSIDFromProgID(OLESTR(“myCom.GetRes”),&clsid);

IGetRes *ptr;

//得到接口IGetRes的指针

hr = CoCreateInstance(clsid, NULL,CLSCTX_INPROC_SERVER, __uuidof(IGetRes), (LPVOID*) &ptr);

//调用IGetRes接口的Hello()函数

Ptr->Hello();

CoUninitialize();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值