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
}