11

这可能是一个菜鸟 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中使用这个实例

摘要:我的方法“似乎”有效,但我不相信它,围绕 COM 对象创建的令人不安的信息太多,不能仅依赖于可观察的行为。

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

4

5 回答 5

5

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

同样,CoCreateInstance这是一个很长的弯路,因为 COM 是语言中立的,并且不知道是否必须使用mallocor创建对象new。你这样做了,所以绕过整个 COM 逻辑。

于 2012-10-24T16:03:36.923 回答
1

这取决于您要实例化的具体内容。当你应该提供一个 COM 指针时,没有人会问你它是用 COM API 实例化的,还是new,或者它有时甚至可以是堆栈上的对象(前提是你设法确保在所有引用被释放之前它不会在堆栈上被销毁) .

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

于 2012-10-24T16:02:29.103 回答
1

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

于 2012-10-24T16:04:56.940 回答
0

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

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

于 2012-10-24T16:04:11.973 回答
-1

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

于 2012-10-24T17:48:55.720 回答