ATL库组件

来源:互联网 发布:c语言开发webservice 编辑:程序博客网 时间:2024/06/05 08:36
ATL库的使用

    1 ATL(Active Template Library)库

是一个模板库,封装了COM SDK相关细节,以及接口和组件实现的相关的机制

    2 ATL接口的相关类

    内部封装了IUnknown接口
2.1 CComObjectRootBase模板类
封装了引用计数,以及内部接口函数等相关的内部调用函数
2.2 CComObjectRootEx
父类是CComObjectRootBase,是一个模板类,封装了对引用计数的增加和减少函数
2.3 CComSingleThreadModel
实现了对引用计数的++和--操作(用于单线程)
2.4 CComMultiThreadModel
实现了对引用计数的原子锁的++和——操作(用于多线程)
2.5 CComObject 模板类
实现了组件、IUnknown接口的函数,提供了组件创建函数

CComSingleThreadModel和CComMultiThreadModel作为模板参数构造CComObjectRootEx对象

    3 使用ATL编写组件

    #include "atlbase.h"   //必须在前面
    #include "atlcom.h"
3.1 IDL定义接口  必须import "objidl.idl";
3.2 增加ATL库的头文件
#include "atlbase.h"
#include "atlcom.h"
3.3 添加组件的实现类,并且继承CComObjectRootEx和IMath接口
3.4 添加接口查询宏
BEGIN_COM_MAP(CMath)
COM_INTERFACE_ENTRY(IMath)
END_COM_MAP()
3.5 添加和实现IMath接口的函数
IUnknown* pIUnknown = NULL;
CComObject<CMath>* pMath = NULL;
CComObject<CMath>::CreateInstance(&pMath);
pMath->QueryInterface(IID_IUnknown, (LPVOID*)&pIUnknown);
return pIUnknown;
3.3 导出接口

    4 代码过程

4.1 CComObject<CMath>;实际是基于组件CMath派生子CComObject,
例如 class CComObject:public CMath
在CComObject类当中实现了IUnknown接口的3个函数,
4.2 在CComObject中AddRdf和Release函数分别调用CMath的父类
CComObjectRootEx提供的InternalAddRef/InternalRelease实现引用计数的加减
4.3 在InternalAddRef/InternalRelease中会调用CComObjectRootEx的模板参数所提供的加减函数完成引用计数的加减
模板参数
CComSingleThreadModel
CComMultiThreadModel
例如    CComObjectRootEx<CComMultiThreadMOdel>
{
   InternalAddRef()
   {
CComMultiThreadModel::InCreme
   }
}
4.4 在CComObject中QueryInterace函数会调用CMath::_InternalQueryInterace,

4.5 CMath::_InternalQueryInterace是通过BEGIN_COM_MAP/END_COM_MAP添加,并且内部调用了父类CComObjectRootBase提供的InternalQueryInterace函数

代码示例:

comobj.idl

import "oaidl.idl";import "ocidl.idl";import "objidl.idl";[object,uuid(033F167D-6FFD-47EC-A450-34A3E45E55CE)]interface IMath :IUnknown{HRESULT Add(long nAdd1, long nAdd2, long* pnAdd) = 0;HRESULT Sub(long nSub1, long nSub2, long* pnSub) = 0;};[uuid(77B18693-AE5A-409D-9C01-5FEAE163153D)]coclass ComObj{interface IMath;};

Math.h

#pragma once//ATL库头文件#include "atlbase.h"#include "atlcom.h"#include "comobj_h.h"extern const CLSID CLSID_Math;class CMath :public CComObjectRootEx<CComMultiThreadModel>,public IMath,public CComCoClass<CMath, &CLSID_Math>{public:CMath();~CMath();public://用于接口查询等相关信息的宏BEGIN_COM_MAP(CMath)COM_INTERFACE_ENTRY(IMath)END_COM_MAP()//IMath接口的函数public:STDMETHOD(Add)(long nAdd1, long nAdd2, long* pnAdd);STDMETHOD(Sub)(long nSub1, long nSub2, long* pnSub);};

Math.cpp

#include "stdafx.h"#include "Math.h"CMath::CMath(){}CMath::~CMath(){}STDMETHODIMP CMath::Add(long nAdd1,long nAdd2,long* pnAdd){*pnAdd = nAdd1 + nAdd2;return S_OK;}STDMETHODIMP CMath::Sub(long nSub1,long nSub2,long* pnSub){*pnSub = nSub1 - nSub2;return S_OK;}

组件创建函数

IUnknown* MyCreateInstance(){IUnknown* piUnknown = NULL;//定义组件对象的指针CComObject<CMath>* pMath = NULL;//创建组件对象CComObject<CMath>::CreateInstance(&pMath);//获取IUnknown接口pMath->QueryInterface(IID_IUnknown,(LPVOID*)&piUnknown);return piUnknown;}



0 0
原创粉丝点击