使用C ++“operator new”而不是CoCreateinstance来创建COM对象是否安全?

时间:2012-10-24 15:48:20

标签: c++ com

这可能是一个菜鸟COM问题,但谷歌搜索引发的问题多于提供答案:

对于本地COM实例,使用“operator new”代替CoCreateInstance是否安全?

我做了什么:

  1. 我实现了IOperationsProgressDialog接口 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775368(v=vs.85).aspx 通过使用公共继承,从而也实现了IUnknown接口。

  2. 我通过“new RecyclerProgressCallback”创建了一个实例,并将其放入COM-Ptr进行终身管理。 “RecyclerProgressCallback”是我派生类的名称。

  3. 我在IFileOperation :: SetProgressDialog中使用此实例 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775803(v=vs.85).aspx

  4. 总结:我的方法似乎“似乎”有效,但我不相信它,围绕可观察行为的COM对象创建过于令人不安的信息。

    是否存在任何微妙的风险,谬误或其他问题?谢谢!

5 个答案:

答案 0 :(得分:5)

我甚至把它们放在堆叠上。 Andrey的答案(现已删除)错误地暗示它不安全,因为您绕过COM引用计数。这是错误的推理。 COM不计算引用;它将责任委托给你。 COM在其最后一个界面上调用delete方法后,您必须调用free()Release或您的语言使用的任何语言。重要的是之后的,因为你没有义务立即这样做。

同样地,CoCreateInstance是一个长途迂回,因为COM与语言无关,并且不知道是否必须使用mallocnew创建对象。你这样做,所以绕过整个COM逻辑。

答案 1 :(得分:1)

这取决于你究竟要实例化的内容。当您应该提供COM指针时,没有人会询问您是使用COM API实例化了还是new,或者它有时甚至可以是堆栈上的对象(前提是您确保它在堆栈之前没有被销毁)所有参考文献都已发布。)

所以答案是肯定的,你可以使用new而且没关系。但是,无论如何它应该是一个有效的COM接口,它应该实现引用计数和QueryInterface COM对象的方式。

答案 2 :(得分:1)

CoCreateInstance API将查看registry找到与指定CLSID匹配的模块,加载它并通过机制(它取决于您的代码是DLL还是EXE)它会调用一些函数来创建对象。因此,为了使CoCreateInstance能够正常工作,您应该编写一个实现IClassFactory COM接口的类,并在注册表中注册,然后调用CoCreateInstance用你的代码做一些额外的工作,至少做你可爱的operator new,然后当然是安全的。通常,在代码中调用operator new接口(仅为回调声明的接口)的source实现始终是安全的,这也是首选方式。

答案 3 :(得分:0)

这样可以正常工作。这就是COM服务器通常在内部创建其对象的方式(至少一个用C ++编写)。从您的角度来看,RecyclerProgressCallback类只是一些C ++代码。您可以将其视为程序中的任何其他类。

话虽如此,COM是一个微妙陷阱的雷区。我不能保证你不会遇到课堂上的问题,但我可以向你保证,这些问题与你使用operator new无关。

答案 4 :(得分:-1)

它通常不安全,不仅仅是因为引用计数,还因为编组:类可能有一个需要编组的线程模型。如果是这种情况,CoCreateInstance将创建代理和存根,而new则不会。