计算机应用 | 古代文学 | 市场营销 | 生命科学 | 交通物流 | 财务管理 | 历史学 | 毕业 | 哲学 | 政治 | 财税 | 经济 | 金融 | 审计 | 法学 | 护理学 | 国际经济与贸易
计算机软件 | 新闻传播 | 电子商务 | 土木工程 | 临床医学 | 旅游管理 | 建筑学 | 文学 | 化学 | 数学 | 物理 | 地理 | 理工 | 生命 | 文化 | 企业管理 | 电子信息工程
计算机网络 | 语言文学 | 信息安全 | 工程力学 | 工商管理 | 经济管理 | 计算机 | 机电 | 材料 | 医学 | 药学 | 会计 | 硕士 | 法律 | MBA
现当代文学 | 英美文学 | 通讯工程 | 网络工程 | 行政管理 | 公共管理 | 自动化 | 艺术 | 音乐 | 舞蹈 | 美术 | 本科 | 教育 | 英语 |

C++类的动态组件化技术(7)

2013-10-19 01:11
导读:3.1. 复杂类型的传入参数 ATL接口方法获取一个接口指针参数后,如何将此接口指针转变为C++对象指针?对于ATL对象,可以直接取得m_pCPPObj变量,而接口指针

  3.1. 复杂类型的传入参数

  ATL接口方法获取一个接口指针参数后,如何将此接口指针转变为C++对象指针?对于ATL对象,可以直接取得m_pCPPObj变量,而接口指针却不能。所以,需要提供一种途径,从ATL接口指针获取ATL组件的m_pCPPObj变量值。

  我们的设计是,为每个ATL组件提供一个基接口ICPPObjSeeker,实现对绑定C++对象指针(即m_pCPPObj)的查询方法HandleCPPObj。任意ATL接口都从该基接口派生,都可以调用HandleCPPObj方法。

  在前文就生命周期进行讨论时,曾提到这样一种情况:客户创建了一个组件,然后送交集合型组件管理。在集合型组件获取外部创建的组件的同时,需要:

  l 取得后者的C++对象指针。集合型组件对元素组件管理的实质是通过集合型C++对象对元素的C++对象进行管理,而集合型ATL对象和元素ATL对象之间并没有直接联系

  l 修改新加入元素组件的维护标识

  因此,我们为ICPPObjSeeker接口添加PostCPPObj方法,用于实现以上功能。

  ICPPObjSeeker接口idl定义如下所示,因为ICPPObjSeeker接口和HandleCPPObj、PostCPPObj方法实际上都应用于内部,所以使用“hidden”属性对外隐藏:

  [

       object,

       uuid(1E9F7F79-936D-4680-9F8E-34A7DCCFF818),

       dual,

       hidden,

       helpstring("ICPPObjSeeker Interface"),

       pointer_default(unique)

  ]

interface ICPPObjSeeker : IDispatch

{

       [id(1), helpstring("取得C++对象的指针"), hidden]

              HRESULT HandleCPPObj([out, retval] long* pCPPObj);

       [id(2), helpstring("取得C++对象的指针,客户程序不再负责对C++对象生命周期的维护"), hidden]

              HRESULT PostCPPObj([out, retval] long* pCPPObj);

};

ICPPObjSeeker接口的方法可以放在CCPP2ATLTemplateBase模板基类中统一实现:

template <class T>

class CCPP2ATLTemplateBase :

{

              ……

       /**********************************************************

         HandleCPPObj函数,由ICPPObjSeeker接口定义,

         负责取得ATL接口中的C++对象指针

       **********************************************************/

       STDMETHODIMP HandleCPPObj(long *pCPPObj)

       {

              AFX_MANAGE_STATE(AfxGetStaticModuleState())

              *pCPPObj = (long)m_pCPPObj;

              return S_OK;

       }

       /**********************************************************

         PostCPPObj函数,由ICPPObjSeeker接口定义,

         负责取得ATL接口中的C++对象指针,

         同时标记对象为内部维护,客户不再负责对象的生命周期管理

       **********************************************************/

       STDMETHODIMP PostCPPObj(long *pCPPObj)

       {

              AFX_MANAGE_STATE(AfxGetStaticModuleState())

              *pCPPObj = (long)m_pCPPObj;

              if (m_bInnerManage == FALSE) {

                     m_bInnerManage = TRUE;

                     m_pCPPObj->m_pAssociATLUnk = this;

                     m_pCPPObj->m_pAssociATLUnk->AddRef();

              }

              return S_OK;

       }

       };

  现在,所有的接口都不再直接从IDispatch派生,而改从ICPPObjSeeker派生,因此,IDispatch的实现也应该在实现ICPPObjSeeker接口的同一级或下级中提供。为了包容IDispatch,我们将ATL模板基类稍作改动:

template <class T, class Q, const IID* piid, const GUID* plibid = &CComModule::m_libid>

class ATL_NO_VTABLE CCPP2ATLTemplateBase :

       public IDispatchImpl<Q, piid, plibid>

{

       ……

};

上一篇:家庭自动化系统 下一篇:没有了