使用哪些COM智能指针类?

15

我对C++编程中的COM智能指针类选择感到困惑:

目前我知道有 三种 四种选择:

  • ATL 中的 CCOMPtr
  • MS Com Support Classes 中的 _com_ptr_t
  • TComInterface (因为我正在使用 C++Builder 2009)
  • CCOMQIPtr(我之前忘记了这个)

我已经了解了前两者的错误处理和异常处理的差异,但是 TComInterface 似乎完全没有记录。从我所了解的情况来看,前两者都存在意外行为或陷阱。

理想情况下,我希望找到一种干净而现代化的 C++ 智能指针,但据我所知,boost::com 并不存在...

我需要通过一个 TLB 文件控制另一个供应商提供的应用程序的 COM 接口。


1
你想做什么?是将COM自动化到另一个应用程序吗?还是托管一个ActiveX控件?或者是为你的应用程序提供COM接口? - Rob
您可能还想讨论BSTR智能包装器。 - morechilli
有一段时间没用了,但我记得我使用过 CComPtr。 - kenny
@Kenny,任何一个都可以完成任务,它们大约相似度为80%。 - Roddy
@morechilli - 当我选择一个包装器时,我可能会使用等效的BSTR包装器。 - Roddy
1
做那个 - Rei Miyasaka
4个回答

6
如果您正在使用类型库导入功能,则会基于_com_ptr_t和相关的COM支持类生成代码。如果您只是使用这些库中的内容,请继续使用它们。
如果您编写基于ATL的代码,则使用CCOMPtr和其他基于ATL的类。
如果您需要混合使用这两种类型,可能会变得很棘手,但您应该熟悉两种类型,并在任何时候使用最合适的类型。
好处是您拥有所有这些东西的源代码,因此不必仅依赖文档(自.NET出现以来,文档已经没有得到充分关注)。

混合使用并不是那么糟糕;你可以来回传递原始接口指针。此外,CComPtr(以及ATL的其他部分)对于ActiveX容器非常方便。ATL不仅仅适用于COM服务器。 - Seva Alekseyev

2
既然您要求“干净和现代”的C ++风格,并且给出boost作为示例,我将再提供两个选择:std / boost :: shared_ptrboost :: intrusive_ptr 。显然,intrusive_ptr是更自然的选择,因为COM对象具有侵入式引用计数机制。shared_ptr同样有效,只需要使用调用IUnknown :: Release()的自定义删除器和执行IUnknown :: AddRef()并返回智能指针的小对象生成函数即可。

我通常使用intrusive_ptr,因此我将详细解释它。首先,当然,必须为所有IUnknown实现intrusive_ptr_add_ref和intrusive_ptr_release。 intrusive_ptr构造函数已经具有方便的功能,可以跳过添加另一个引用,因为许多COM函数将为您执行AddRef()

现在这种方法存在一个问题:intrusive_ptr不像其他COM指针一样公开其基础裸指针。这是一个问题,因为创建COM对象的常见方法是通过向另一个对象的某个创建函数传递指向指针的指针。由于无法将intrusive_ptr传递到这些函数中,因此您最终会得到笨拙的临时裸指针,用于初始化intrusive_ptr。这不是很优雅,更不用说异常安全了(如果您需要在COM代码中使用此功能,它自然不会抛出异常。我将COM错误转换为异常。)

因此,在这里我使用另一个工具函数,该函数将采用任何com函数并返回可调用函数,其中任何指向指针到T的参数可以是那个或者是intrusive_ptr的引用。其他所有内容都与“输入函数”类似。然后,这些函数为我执行T **和intrusive_ptr&之间的所有转换。例如, HRESULT CreateBuffer(IBuffer ** bufferOut,int size)变为带有签名的可调用项 HRESULT CreateBuffer(instrusive_ptr<IBuffer>& bufferOut,int size)。虽然对于“所有”数量来说有点乏味,除非您拥有代码生成器,有很多耐心或者我认为是可变模板。但是一旦你拥有它们,实际上它使与COM一起工作变得非常好。


1

我已经使用了前两个,CComPtr 和 _com_ptr_t。

看起来你已经阅读了有关错误和异常处理的区别,所以选择你最喜欢的或者最符合你代码中其余错误处理方式的那一个。


0
如kenny所提到的,您可以使用CComPtr来管理指向COM接口的指针。这个类有很好的文档(请参见msdn),并且使用自动引用计数,我想这正是您想要的。
另一方面,Rob的问题很重要:您真的使用COM接口吗?对于仅需要指针的情况,您可以使用STL或boost库中的智能指针,它们通常比CComPtr更好。

@maverick - 是的,我需要 COM :-( - Roddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接