深入探索COM开发框架 之 MFC和ATL [二]

原创 2003年04月03日 08:54:00

本来,通过C++编译器的cast转换符具有的对地址偏移的计算能力,可以完成任务,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

不过ATL中还是采用了建表(数据驱动,data-driven)这种策略,以获得更好的性能和

灵活性,事实上,(事实上,就性能而已本人认为差别很小,实质在cast方案中,

每次都从this出发,计算偏移,得到正确的接口入口点.而数据驱动方案,直接可以

直接查询得到接口入口点,因为它在编译时就计算了偏移量,存于表中.)

 

三、宏剖析

                                  MFC

 

PART1----接口基础构造的由来

 

自然,针对MFC采用的类嵌套方案,必须有特殊的构造来支持COM意识行为.

谈到MFCCOM的支持,必须要知道CCmdTarget,它提供了大量的对自动化

的支持,(注:本人感觉MFCCOM的支持,目光总不离开Automation,主要

体现在默认声明的接口为dispinterface,它使得在未知使用环境总是使用

接口的分发,哪怕是C++环境).

 

(重申:本文只针对Inpro组件,来剖析框架,事实上,其它类型的只是基于其上的

扩展.当然COM体系是巨大的.)

 

建立组件类:

在你的.dll文件中,你的组件类需要从CCmdTarget派生.

因为它提供了对COM开发的大量支持.

 

建立接口且实现接口映射表的建立:

-----------------------------------------------------------------------------------------------------------------------------------------

DECLARE_INTERFACE_MAP() 宏剖析

                     ---------------------------------------------------------------------------------------

#ifdef _AFXDLL

#define DECLARE_INTERFACE_MAP() /

private: /

   static const AFX_INTERFACEMAP_ENTRY _interfaceEntries[]; /

       //定义组件类的接口映射表

protected: /

   static const AFX_INTERFACEMAP interfaceMap; /

       //定义AFX_INTERFACEMAP变量,

       //为在当前类中,找不到接口时,

       //回到基类中寻找

       //其中还存储了当前接口映射表的入口点.

   static const AFX_INTERFACEMAP* PASCAL _GetBaseInterfaceMap(); /

       //获得基类的interfaceMap

   virtual const AFX_INTERFACEMAP* GetInterfaceMap() const; /

      //获得组件类的interfaceMap

 

#else

#define DECLARE_INTERFACE_MAP() /

private: /

   static const AFX_INTERFACEMAP_ENTRY _interfaceEntries[]; /

protected: /

   static const AFX_INTERFACEMAP interfaceMap; /

   virtual const AFX_INTERFACEMAP* GetInterfaceMap() const; /

#endif

 

-----------------------------------------------------------------------------------------------------------------------------------
                        BEGIN_INTERFACE_MAP(CSAM, CCmdTarget)[.cpp]

                          //CSAM是组件类名称

                         INTERFACE_PART(CSAM, IID_ICOM, Dispatch)

                        END_INTERFACE_MAP()

                                      宏剖析

                   -------------------------------------------------------------------------------------

#ifdef _AFXDLL

#define BEGIN_INTERFACE_MAP(theClass, theBase) /

             const AFX_INTERFACEMAP* PASCAL theClass::_GetBaseInterfaceMap() /

                 { return &theBase::interfaceMap; } /

             //定义获得基类的interfaceMap首址的静态成员函数

const AFX_INTERFACEMAP* theClass::GetInterfaceMap() const /

            { return &theClass::interfaceMap; } /

          //定义获取组件类接口映射表首址的静态成员函数

   AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP theClass::interfaceMap = /

           { &theClass::_GetBaseInterfaceMap, &theClass::_interfaceEntries[0], }; /

     //填充:基类的GetThisInterfaceMap函数指针和

           //       本组件类的接口映射表入口点

         AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP_ENTRY theClass::_interfaceEntries[] = /

{ /

#else

#define BEGIN_INTERFACE_MAP(theClass, theBase) /

        const AFX_INTERFACEMAP* theClass::GetInterfaceMap() const /

            { return &theClass::interfaceMap; } /

        AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP theClass::interfaceMap = /

           { &theBase::interfaceMap, &theClass::_interfaceEntries[0], }; /

        AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP_ENTRY theClass::_interfaceEntries[] = /

        { /

#endif

#define INTERFACE_PART(theClass, iid, localClass) /

{ &iid, offsetof(theClass, m_x##localClass) }, /

//填充接口影射表

 

#define INTERFACE_AGGREGATE(theClass, theAggr) /

        { NULL, offsetof(theClass, theAggr) }, /

//值得讲一下的是,MFC支持COM的手法有组件聚合之感觉

//

 #define END_INTERFACE_MAP() /

                 { NULL, (size_t)-1 } /

}; /

//标志接口映射表结束

#endif //!_AFX_NO_OLE_SUPPORT

----------------------------------------------------------------------------------------------------------------------------------------------

   上面两组宏,离不开AFX_INTERFACE_ENTRY结构和AFX_INTERFACE结构.

下面我们来看看这两个结构:

  struct AFX_INTERFACEMAP_ENTRY//接口映射表结构

{

        const void* piid;       // 接口标志符 (NULL for aggregate)

        size_t nOffset;         // offset of the interface vtable from m_unknown

                         //接口(嵌套类)和包裹类的偏移量

};

  struct AFX_INTERFACEMAP

{

#ifdef _AFXDLL

       const AFX_INTERFACEMAP* (PASCAL* pfnGetBaseMap)(); // NULL is root class

                       //定义函数指针

#else

       const AFX_INTERFACEMAP* pBaseMap;

                       //

#endif

       const AFX_INTERFACEMAP_ENTRY* pEntry; // map for this class

                      //接口映射表入口点指针

};

上面的两组宏是干什么的呢?

它们在组件类的内部做了下面几样事情:(define _AFXDLL分析)

1.        建立了接口映射表.

表的结构为AFX_INTERFACEMAP_ENTRY

此结构记录了piid,接口标志符和

接口与包裹类的偏移量

          实际动作如下:

      #define INTERFACE_PART(theClass, iid, localClass) /

{ &iid, offsetof(theClass, m_x##localClass) }, /

 

 

 

 

 

 

 

我的COM和ATL的学习

首先声明本人并非COM/ATL高手,尽管本人接触他们已经有4年了,但是因为工作中的一些原因一直未能深入研究和广泛的实际的使用它们。不过回想学习它们的痛苦经历,实在是有点不堪回首。在此仅以此文和大家探讨...
  • chenlycly
  • chenlycly
  • 2014年10月12日 17:33
  • 891

COM组件开发(六)——使用ATL开发COM组件

使用ATL开发COM组件           使用ATL开发COM组件之前,要对几个重要的类进行说明:           CComModule           这是ATL的中心模块类,它的...
  • q5806622
  • q5806622
  • 2015年02月27日 10:10
  • 2230

ATL和MFC创建ActiveX控件的区别

ATL和MFC创建ActiveX控件的区别 ATL和MFC创建ActiveX控件的区别 在visual C++ 6.0中,ATL和MFC代表了两种不同的框架,分别面向不同类型的基于Window...
  • ljh081231
  • ljh081231
  • 2014年04月11日 10:18
  • 4602

VS2010 简单ATL COM开发(下)

前面一章介绍了怎么创建ATL COM组件及注册,下面简单介绍如何调用COM组件。 1、在MFC中调用有一种很方便的方法,就是通过ClassWizard利用类型库生成包装类,不过有个前提就是com...
  • wangwenjing90
  • wangwenjing90
  • 2013年04月08日 15:11
  • 12972

VS2010 简单ATL COM开发(上)

1、打开VS2010,新建ATL COM 项目,步骤:“文件” --》“新建” --》“项目”,选择“Visual C++” --》“ATL 项目” ,填写“名称” FirstCOM --》“确定”。...
  • wangwenjing90
  • wangwenjing90
  • 2013年04月08日 14:03
  • 17734

创建ATL工程及使用MFC测试COM组件

一、创建ATL工程 1、创建ATL项目,取名为MyATL 2、在ATL项目向导中,勾选【支持MFC】(利用MFC测试用)、【支持 COM+ 1.0】和【支持部件注册器】,其余的选项默认,点击完...
  • jiangqin115
  • jiangqin115
  • 2015年09月06日 17:47
  • 797

[COM/ATL]组件、对象、MFC、ATL的区别

组件(Component)和对象(Object)之间的区别 先明确组件(Component)和对象(Object)之间的区别。组件是一个可重用的模块,它是由一 组处理过程、数据封装和用户接口组成的业...
  • ouyangshima
  • ouyangshima
  • 2013年07月19日 19:58
  • 1539

OLE、ActiveX、COM、ATL联系与区别

熟悉面向对象编程和网络编程的人一定对ActiveX、OLE和COM/DCOM这些概念不会陌生,但是它们之间究竟是什么样的关系,对许多们还是比较模糊的。在具体介绍它们的关系之间,我们还是先明确组件(Co...
  • lp310018931
  • lp310018931
  • 2015年09月19日 18:09
  • 1026

COM组件(ATL篇)

目 录 第1章 创建进程内组件    1 1.1 目标    1 1.2 创建项目    3 1.2.1 VC++6.0    3 1.2....
  • Hanford
  • Hanford
  • 2016年11月25日 21:45
  • 1082

C++ STL,ATL,WTL之间的联系和区别

STL即 Standard Template Library (标准模板库) STL是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和Davi...
  • xdrt81y
  • xdrt81y
  • 2013年12月05日 16:09
  • 11293
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入探索COM开发框架 之 MFC和ATL [二]
举报原因:
原因补充:

(最多只允许输入30个字)