本文共 2905 字,大约阅读时间需要 9 分钟。
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 , public IMath, public CComCoClass {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 * pMath = NULL; //创建组件对象 CComObject ::CreateInstance(&pMath); //获取IUnknown接口 pMath->QueryInterface(IID_IUnknown, (LPVOID*)&piUnknown); return piUnknown;}
转载地址:http://szxui.baihongyu.com/