这可能是一个菜鸟COM问题,但谷歌搜索引发的问题多于提供答案:
对于本地COM实例,使用“operator new”代替CoCreateInstance是否安全?
我做了什么:
我实现了IOperationsProgressDialog接口 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775368(v=vs.85).aspx 通过使用公共继承,从而也实现了IUnknown接口。
我通过“new RecyclerProgressCallback”创建了一个实例,并将其放入COM-Ptr进行终身管理。 “RecyclerProgressCallback”是我派生类的名称。
我在IFileOperation :: SetProgressDialog中使用此实例 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775803(v=vs.85).aspx
总结:我的方法似乎“似乎”有效,但我不相信它,围绕可观察行为的COM对象创建过于令人不安的信息。
是否存在任何微妙的风险,谬误或其他问题?谢谢!
答案 0 :(得分:5)
我甚至把它们放在堆叠上。 Andrey的答案(现已删除)错误地暗示它不安全,因为您绕过COM引用计数。这是错误的推理。 COM不计算引用;它将责任委托给你。 COM在其最后一个界面上调用delete
方法后,您必须调用free()
或Release
或您的语言使用的任何语言。重要的是之后的。 时,因为你没有义务立即这样做。
同样地,CoCreateInstance
是一个长途迂回,因为COM与语言无关,并且不知道是否必须使用malloc
或new
创建对象。你这样做,所以绕过整个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
则不会。