用ATL建立轻量级的COM对象(2)

http://tech.ddvip.com   2006年07月21日    社区交流

本文详细介绍用ATL建立轻量级的COM对象(2)

  起步篇

  在本文的第一部分,我们简要介绍了ATL的一些背景知识以及ATL所面向的开发技术和环境。在这一部分 将开始走进ATL,讲述ATL编程的基本方法、原则和必须要注意的问题。

  理解ATL最容易的方法是考察它对客户端编程的支持。对于COM编程新手而言,一个棘手的主要问题之一是正确管理接口指针的引用计数。COM的引用计数法则是没有运行时强制 性的,也就是说每一个客户端必须保证对对象的承诺。

  有经验的COM编程者常常习惯于使用文档中(如《Inside OLE》)提出的标准模式。调用某个函数或方法,返回接口指针,在某个时间范围内使用这个接口指针,然后释放它。下面是使用这种模式的代码例子:

void f(void) {
  IUnknown *pUnk = 0;
  // 调用
  HRESULT hr = GetSomeObject(&pUnk);
  if (SUCCEEDED(hr)) {
  // 使用
   UseSomeObject(pUnk);
// 释放
   pUnk->Release();
  }
}
  
  这个模式在COM程序员心中是如此根深蒂固,以至于他们常常不写实际使用指针的语句,而是先在代码块末尾敲入Release语句。这很像C程序员使用switch语句时的条件反射一样,先敲入break再说。

  其实调用Release实在不是什么可怕的负担,但是,客户端程序员面临两个相当严重的问题。第一个问题与获得多接口指针有关。如果某个函数需要在做任何实际工作之前获得三个接口指针,也就是说在第一个使用指针的语句之前必须要由三个调用语句。在书写代码时,这常常意味着程序员需要写许多嵌套条件语句,如:

  void f(void) {
 IUnknown *rgpUnk[3];
 HRESULT hr = GetObject(rgpUnk);
 if (SUCCEEDED(hr)) {
  hr = GetObject(rgpUnk + 1);
  if (SUCCEEDED(hr)) {
   hr = GetObject(rgpUnk + 2);
   if (SUCCEEDED(hr)) {
    UseObjects(rgpUnk[0], rgpUnk[1],
           rgpUnk[2]);
    rgpUnk[2]->Release();
   }
   rgpUnk[1]->Release();
  }
  rgpUnk[0]->Release();
 }
}
  
  像这样的语句常常促使程序员将TAB键设置成一个或两个空格,甚至情愿使用大一点的显示器。但事情并不总是按你想象的那样,由于种种原因项目团队中的COM组件编程人员往往得不到 所想的硬件支持,而且在公司确定关于TAB键的使用标准之前,程序员常常求助于使用有很大争议但仍然有效的“GOTO”语句:

责编:豆豆技术应用

正在加载评论...