设为首页 加入收藏

TOP

COM编程技术基础之二(三)
2012-11-04 15:22:07 来源: 作者: 【 】 浏览:707
Tags:COM 编程 技术 基础 之二
  COM规范允许使用多接口,QueryInterface()成员函数可以用来查询组件是否支持某个特定的接口。如果支持,QueryInterface()将返回此接口的指针。其第一个参数为一个IID结构,指出了客户所要查询的接口,查询到的接口指针将存放在ppv所指向的变量中。函数的成功执行与否将返回S_OK或E_NOINTERFACE。但是,在使用时不能简单的将QueryInterface()返回值与其进行比较,而应使用SUCCEEDED或FAILED宏。例如:

IUnknow* pI = CreateInstance();
IX* pIX = NULL;
HRESULT hResult = pI->QueryInterface(IID_IX, (void**)&pIX);
if (SUCCEEDED(hResult))
 pIX->Func1();

  由于QueryInterface()过于灵活,为避免由此引发的冲突在COM规范中定义了QueryInterface()所有实现都必须遵循的一些规则:

  1) 过同一对象各个接口指针所查询得到的IUnknown接口指针必须是指向同一个IUnknown接口的。即,IUnknow接口的唯一性。

  2) 如果某接口曾经被成功查询过,那么此后任何时间对该接口的查询也必定会成功。即,接口与查询时间的无关性。

  3) 对于已经获取到的接口仍可对其进行再次查询,并且必定会成功。即,接口的自反性。

  4) 客户能够从任何接口查询到另外一个接口,而且能够返回到起始接口。即,接口的对称性。

  5) 如果能够从某接口获取到某特定接口,那么从任意接口都可以得到此接口。即,接口的传递性。

  IUnknown接口的另两个成员函数AddRef()和Release()对对象的生存期进行了控制。每个COM对象都记录有一个引用计数,该引用计数表示了当前引用了此COM对象的有效指针的个数。AddRef()和Release()实现的即是这种引用计数的内存管理技术:引用计数初始为0,客户每得到一个指向此对象的接口指针即通过AddRef()将引用计数加1;在每用完此接口指针后,调用Release()函数将引用计数减1。如果引用计数减到0,则从内存卸载掉此COM对象。关于引用计数的使用,在COM规范中也设置了以下几条简单的规则:

  1) 任何能够返回接口指针的函数(如QreryInterface()、CreateInstance()等)在返回接口指针之前,必须用相应的指针调用AddRef()函数。

  2) 在使用完任何一个接口后,应及时调用该接口的Release()函数。

  3) 在进行接口指针赋值操作后,应调用AddRef()函数。

  COM组件的创建可以通过CoCreateInstance()函数来完成,函数原型为:

HRESULT __stdcall CoCreateInstace(
 const CLSID& clsid,
 IUnknown* pIUnknownOuter,
 DWORD dwClsContext,
 const IID& iid,
 void** ppv
);

  函数参数clsid是要创建组件的CLSID,pIUnknownOuter用于聚合组件,如果不使用可以设置为NULL。参数dwClsContext则限定了所创建组件的执行上下文。最后两个参数iid和ppv则分别为要使用接口的IID和返回得到的接口指针。在使用时只需将CLSID、IID等作为参数传入即可创建相应的组件并从输出参数ppv得到所请求接口的指针。如果函数是直接创建组件的,那么在函数返回时组件将创建完毕,这样客户将无法对组件的创建过程进行任何干预,灵活性太差。因此,CoCreateInstance()在函数内部实现中通过调用CoGetClassObject()函数先创建一种专门用来创建组件的组件来解决此问题。这种用途的组件被称为类厂(class factory)。

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇ATL简介 下一篇COM编程技术基础之一

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: