C++ COM-CoCreateInstanceEx始终创建一个新对象

C++ COM-CoCreateInstanceEx始终创建一个新对象,c++,com,C++,Com,我正在使用COMCoCreateInstanceExAPI在本地计算机上创建特定类的实例 我再次使用相同的函数来获取先前创建的实例,但它创建了一个新实例 从运行的实例获取类的对象是正确的方法还是应该使用其他方法 C++代码段: HRESULT nResult = CLSIDFromProgID(OLESTR("ABC"), &clsid); MULTI_QI mqi[1]; mqi[0].pIID = &IID_IUnknown; mqi[0].pItf = NULL; mqi[

我正在使用COM
CoCreateInstanceEx
API在本地计算机上创建特定类的实例

我再次使用相同的函数来获取先前创建的实例,但它创建了一个新实例

从运行的实例获取类的对象是正确的方法还是应该使用其他方法

C++代码段:

HRESULT nResult = CLSIDFromProgID(OLESTR("ABC"), &clsid);
MULTI_QI mqi[1];
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = 0;

nResult = CoCreateInstanceEx(clsid, NULL, CLSCTX_LOCAL_SERVER, NULL, 1, mqi); 

IUnknown *pUnk = mqi[0].pItf;
从运行的实例获取类的对象是正确的方法还是应该使用其他方法

不,不是
CoCreateInstanceEx
深入研究COM工厂机制,获取所需对象的工厂,并创建一个新工厂

要获得上次使用的同一实例的“副本”,有一些选项可供选择

  • 对第一个创建的对象调用
    AddRef()
    ,以增加即将创建的对象指针副本的COM对象引用计数。然后使用该指针直到不再需要它,然后调用
    Release()
    Release()。这不会执行对象及其内容的深度复制
  • 如果您有权访问代码,则可以将COM对象设置为单例对象,或者根据需要修改生存期。如果COM对象代码使用ATL,这里有几个宏可以提供帮助,尤其是
  • 在执行深度复制的COM对象上创建一个
    Clone()
    方法,这里的确切机制将取决于对象本身,但通常它只不过是适当数据字段的常规方法
不过坦率地说,除非这是学习COM如何工作的练习,不要使用裸指针,而是尝试手动管理对象的生命周期。特别是使用ATL类,它会像您期望的那样处理这些问题


您没有太详细地指定创建对象的方式和位置。有更先进的对象注册和检索技术,允许对对象的创建、生存期和使用进行更高级别的控制。如果它们合适的话,你可以探索它们

  • 等的活动对象机制
  • 如果正在使用的对象将自己注册到ROT(运行对象表),您还可以

  • 要从正在运行的实例中获取现有对象,可以使用running objects表(ROT)。我记得这是通过名字做的。但那是很久以前的事了,看看吧。你可以用谷歌搜索一些现有的解决方案,而不是通过跳转来实现它。谷歌搜索了它,结果是
    GetActiveObject
    。还有较低级别的
    CoGetObject
    ,它依次使用,依此类推。不幸的是,所有这些函数都存在过度工程化、不必要的复杂性。您正在“再次使用相同的函数来获取…”,而MSDN明确指出此函数“创建未初始化的实例”。您实际得到的显然是设计的行为。@Cheersandhth.-Alf:使用GetActiveObject方法进行了检查,但没有成功,可能我遗漏了一些步骤。@M.M-是的。@Niall提供了建议,我已经尝试使用“GetActiveObject”和ROT表了。对于ROT表,我需要创建“IMoniker”对象,我需要标识对象的对象名称。我需要为相同的名称找到唯一的名称。@VirajAbhange。听起来不错。ActiveObject和ROT需要创建的COM对象的协作。您提供的代码示例并不完全清楚您的意图,但我认为一个简单的
    AddRef
    就可以了,或者更好地使用ATL。