将 COM 对象动态转换为 COM 接口不会增加引用计数,不是吗?

发布于 2024-08-05 15:59:30 字数 287 浏览 15 评论 0原文

如果我有一个 C++ 类 X,它实现了 COM 接口 IY 和 IZ,并且我有一个指向 X 类型对象的 IY 接口的指针 y,我会这样做:

IZ *z = dynamic_cast<IZ *> ( y );

这不会增加对象的引用计数,是吗?我不必执行 Release() 来解释它,对吧?

如果重要的话,我正在使用 ATL/COM。

我猜答案是“不,它不会增加引用计数,而且你不必 Release()”,但我想确定一下。

提前致谢。

If I have a C++ class, X, which implements the COM interfaces IY and IZ, and I have a pointer y to the IY interface of an object of type X, and I do this:

IZ *z = dynamic_cast<IZ *> ( y );

That doesn't bump the object's reference count, does it? I don't have to do a Release() to account for it, right?

If it matters, I'm using ATL/COM.

I'm guessing the answer is "no it doesn't bump the reference count, and no you don't have to Release()", but I want to make sure.

Thanks in advance.

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

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

发布评论

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

评论(3

捎一片雪花 2024-08-12 15:59:30

不得使用dynamic_cast有多种原因:

  • 您不知道目标是否支持RTTI
  • 您不确定OLE是否不会为您创建代理
  • ...

而是使用QueryInterface - 它会做您想要的事情。

即使您确定上面有问题 - 转换不会改变引用计数器

dynamic_cast must not be used on multiple reasons:

  • You don't know if destination supports RTTI
  • You not sure if OLE doesn't create proxy for you
  • ...

Instead use QueryInterface - it would done what you want.

Even if you sure in question above - casting doesn't changes refcounter

迷你仙 2024-08-12 15:59:30

当有人调用 IUnknown::AddRef() 时,COM 对象的引用计数就会增加。 QueryInterface()根据COM规则,因为它给出了一个新的接口指针,所以内部调用AddRef()。

在您发布的代码中,您没有调用 AddRef(),也没有调用任何可能调用 AddRef() 的函数,那么您为什么认为引用计数会增加呢?

尽管 ATL/MFC 对大脑做了什么,但并没有什么魔力。如有疑问,您可以随时在 VS 中查看反汇编代码并逐步执行它,并向自己证明 AddRef() 没有被调用。

编辑:我想重申 Dewfy 所说的,不要这样做。使用 QueryInterface()。或CComQIPtr<> (如果你真的必须的话)。

进一步编辑:如果您使用 CComPtr<>和CComQIPtr那么您就不必调用 Release() 并且减轻了确定正确引用计数的大部分负担。你真的应该考虑使用它们。

Reference counts for COM objects are incremented when someone calls IUnknown::AddRef(). QueryInterface(), according to COM rules since it gives out a new interface pointer, internally calls AddRef().

In your posted code, you're not calling AddRef(), and you're not calling any function that might call AddRef(), so why would you think the reference count would be incremented?

Despite what ATL/MFC does to one's brain, there is no magic involved. When in doubt, you can always view the disassembly in VS and step through it and prove to yourself that AddRef() isn't being called.

Edit: And I want to reiterate what Dewfy said, don't do this. Use QueryInterface(). Or CComQIPtr<> (if you really must).

Further edit: If you use CComPtr<> and CComQIPtr<> then you don't have to call Release() and much of the burden of figuring out the proper ref-counting is alleviated. You should really consider using them.

薔薇婲 2024-08-12 15:59:30

在 C++Builder 中,COM 接口指针上的 dynamic_cast 实际上执行 QueryInterface 操作。如果 QI 成功,则返回的指针将被 AddRef 处理。

实现 COM 对象的类与更通用的 C++ 类具有不同的 vtable 布局,因此 C++ 样式的 dynamic_cast 无法工作;所以我想这就是为什么 C++Builder 做 QueryInterface 更明智的事情。

(COM 最初的想法是将 C++ 对象模型推广为与语言无关的二进制标准;他们将dynamic_cast 重命名为 QueryInterface)。

我猜最重要的答案是指 MSVC,如果dynamic_cast 导致未定义的行为。

In C++Builder, dynamic_cast on a COM interface pointer actually does QueryInterface. and the returned pointer, if the QI succeeds, gets AddRef'd.

Classes which implement COM objects have different vtable layouts to more general C++ classes, so a C++-style dynamic_cast cannot work; so I presume this is why C++Builder does the more sensible thing of doing QueryInterface.

(The original idea of COM was to generalize the C++ object model to be language-agnostic and to a binary standard; they renamed dynamic_cast to QueryInterface).

I guess the top answer is referring to MSVC, if dynamic_cast causes undefined behaviour.

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