COM 中 CComPtr 相对于 CComQIPtr 有何用途?

发布于 2024-11-27 02:32:46 字数 162 浏览 5 评论 0原文

任何人都可以解释一下,COM 中 CComPtr 相对于 CComQIPtr 有什么用处?

CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;

Can any one explain, What is the use of CComPtr over CComQIPtr in COM?

CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

天邊彩虹 2024-12-04 02:32:46

CComQIPtr 适用于当您想要以方便的方式调用 QueryInterface() 来了解是否支持接口的情况:

IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
   //supported - use
}

通过这种方式,您可以从指向任何对象的指针请求接口。 (不相关)COM 接口并检查该请求是否成功。

CComPtr 用于管理肯定支持某些接口的对象。您可以将其用作具有引用计数的普通智能指针。它类似于 CComQIPtr,但不允许上述用例,这为您提供了更好的类型安全性。

此代码:

IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );

如果 unknown 绑定到未实现 IDispatch 的对象,则编译并可能生成空指针。现在,您必须在运行时检查这一点,如果您首先想要运行时检查,那么这很好,但如果您更喜欢编译时类型检查,则不好。

这段代码:

IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );

根本无法编译 - 它会产生

错误 C2664:“ATL::CComPtr::CComPtr(IDispatch *) throw()”:无法将参数 1 从“IUnknown *”转换为“IDispatch *”

这提供了更好的编译时类型安全性。

CComQIPtr is for cases when you want to call QueryInterface() in a convenient manner to know whether an interface is supported:

IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
   //supported - use
}

This way you can request an interface from a pointer to any (unrelated) COM interface and check whether that request succeeded.

CComPtr is used for managing objects that surely support some interface. You use it as a usual smart pointer with reference counting. It is like CComQIPtr, but doesn't allow the usecase described above and this gives you better type safety.

This code:

IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );

compiles and maybe yields a null pointer if unknown is bound to an object that doesn't implement IDispatch. You now have to check for that in runtime which is good if you wanted a runtime check in the first place but bad if you'd prefer a compile time type check.

This code:

IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );

will simply not compile - it yields

error C2664: 'ATL::CComPtr::CComPtr(IDispatch *) throw()' : cannot convert parameter 1 from 'IUnknown *' to 'IDispatch *'

which provides for better compile time type safety.

迷雾森÷林ヴ 2024-12-04 02:32:46
template<class T,
   const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>

前者通过默认模板参数自动推导出给定类型的 UUID。

template<class T,
   const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>

Former deduces the UUID of given type automatically, via default template argument.

友谊不毕业 2024-12-04 02:32:46

以下 MSDN 文章解释了其中的差异,并建议使用 CComPtr 而不是 CComQIPtr

如何:创建和使用 CComPtr 和 CComQIPtr 实例

The following MSDN article explains the difference and recommends using CComPtr instead of CComQIPtr

How to: Create and Use CComPtr and CComQIPtr Instances

不…忘初心 2024-12-04 02:32:46

评论sharptooth的答案。只是试图编译某事。喜欢

CComQIPtr<IInterface2> to( from );

却失败了。相反,作业有效:

CComQIPtr<IInterface2> to = from;

不幸的是我没有时间进一步分析这个......

Remark on the answer of sharptooth. Just tried to compile sth. like

CComQIPtr<IInterface2> to( from );

and failed. Assignment instead worked:

CComQIPtr<IInterface2> to = from;

Unfortunately I have no time to analyse this further...

烟酒忠诚 2024-12-04 02:32:46

“ATL 使用 CComQIPtr 和 CComPtr 来管理 COM 接口指针。这两个类都通过调用 AddRef 和 Release 来执行自动引用计数。重载运算符处理指针操作。CComQIPtr 另外还支持通过 QueryInterface 自动查询接口。”

<块引用>

你在哪里使用其中一种而不是另一种?

当您不想“手动”调用“QueryInterface()”时,请使用“CComQIPtr”:

CComQIPtr( T* lp );

CComQIPtr( const CComQIPtr< T, piid >& lp );

如果传递从 T 派生的指针类型,构造函数会将 p 设置为 T* 参数并调用 AddRef。如果传递的指针类型不是从 T 派生的,则构造函数会调用 QueryInterface 将 p 设置为与 piid 对应的接口指针。

"ATL uses CComQIPtr and CComPtr to manage COM interface pointers. Both classes perform automatic reference counting through calls to AddRef and Release. Overloaded operators handle pointer operations. CComQIPtr additionally supports automatic querying of interfaces though QueryInterface."

And where do you use one over the other?

When you do not want to call 'QueryInterface()' 'manually', use 'CComQIPtr':

CComQIPtr( T* lp );

CComQIPtr( const CComQIPtr< T, piid >& lp );

If you pass a pointer type derived from T, the constructor sets p to the T* parameter and calls AddRef. If you pass a pointer type not derived from T, the constructor calls QueryInterface to set p to an interface pointer corresponding to piid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文