C# COM对象清理

C# COM对象清理,c#,c++,com,activex,components,C#,C++,Com,Activex,Components,下面两行代码之间的区别是什么: CComPtr< IInterface > m_interface; IInterface* m_interface; 当我用声明接口指针时:IInterface*m_interface 在C#中测试接口时,我遇到一个RPC_E_SERVERFAULT错误,必须显式调用GC.Collect()以避免在实例化一些对象后引发错误。在VC++中测试接口时,错误是一致的,但发生的时间不同。如果我注释掉IInterface的实例创建,代码运行良好,但是当我尝

下面两行代码之间的区别是什么:

CComPtr< IInterface > m_interface;

IInterface* m_interface;
当我用声明接口指针时:
IInterface*m_interface

在C#中测试接口时,我遇到一个RPC_E_SERVERFAULT错误,必须显式调用GC.Collect()以避免在实例化一些对象后引发错误。在VC++中测试接口时,错误是一致的,但发生的时间不同。如果我注释掉IInterface的实例创建,代码运行良好,但是当我尝试创建一个实例时,我得到了与之前相同的错误,只是一个模糊的未处理异常错误。我做错了什么

CComPtrm_接口是一个对象。而IInterface*m_接口是一个指针

第一个将在其超出范围时调用其析构函数,我认为(我使用它已经很长时间了)它将自动调用m_interface->Release()

后者是指向接口的指针,您必须在调用m_interface->Release()时进行管理


你能确认COM对象在访问之前没有被释放吗?

CComPtr
是一个智能指针,当与COM习惯用法一起使用时,它可以做“正确”的事情

您的
get\u IClass
代码看起来不错,但是
putref\u IClass
需要在
IClass
上调用
AddRef
。如果您使用了
CComPtr
,这将自动发生


您需要添加有关VC++未处理异常的更多详细信息。

IInstance*m_实例是指向IInstance对象的简单指针。您必须自己管理此指针的生命周期。您不会像删除普通对象那样
new
删除
COM对象。相反,当您调用WINAPI函数“CoCreateInstance”时,操作系统会分配对象:

// instantiate the CoClass which implements IInstance...
IInstance* instance = 0;
HRESULT hr = CoCreateInstance(__uuidof(mylibrary::MyCoClass), 0, CLSCTX_INPROC_SERVER, __uuidof(mylib::IInstance), &instance);

:   :

// We're done, so release the object...
instance->Release();
instance = 0;
每个COM对象都实现引用计数。当对对象的最后一次引用被
Release()
ed时,COM对象将销毁自身

使用
CComPtr
简化了管理COM对象生存期的方式。它是一个智能指针,本质上类似于std::auto_ptr或Boost的shared_ptr,但它可用于COM对象。通常,在使用CComPtr时,您会调用
CreateInstance
成员函数,而不是调用WINAPI函数,并且在完成后不会显式调用
Release
。只要让CComPtr超出范围,当调用它的析构函数时,它将为您调用
Release

void function()
{
  // instantiate the CoClass which implements IMyInterface...
  CComPtr<IInstance> instance;
  instance.CoCreateInstance(__uuidof(mylibrary::MyCoClass));

  :   :

  // We're done, so release the object...
  // dont have to do anything, it will be released when function() exits
}
void函数()
{
//实例化实现IMyInterface的CoClass。。。
CComPtr实例;
CoCreateInstance(uuuidof(mylibrary::MyClass));
:   :
//我们完成了,所以释放这个物体。。。
//不必执行任何操作,它将在函数()退出时释放
}

谢谢。我对我的问题进行了一些编辑,以提供更多信息。我在VC++代码测试接口实现中调用Release()。这没有帮助,我怀疑我需要释放/销毁非托管代码中的对象,即使在使用CComPtr时也是如此,但我不确定。@Reggie:有时确实需要对对象调用AddRef/release,即使它是由CComPtr管理的。您需要向我们展示VC++代码,这样我们才能看到您是否做错了什么。谢谢。这有助于更好地理解。我会投票支持你,但我没有足够的信誉点。你真的应该花15分钟制作一个非常简短的代码片段来演示这个问题。你说“使用VC++中的接口,我会遇到一个未经处理的异常错误”-你能给我们展示一下使用VC++中的接口的代码吗?
void function()
{
  // instantiate the CoClass which implements IMyInterface...
  CComPtr<IInstance> instance;
  instance.CoCreateInstance(__uuidof(mylibrary::MyCoClass));

  :   :

  // We're done, so release the object...
  // dont have to do anything, it will be released when function() exits
}