以下两行代码有什么区别:
CComPtr< IInterface > m_interface;
IInterface* m_interface;
我知道CComPtr有助于消除内存泄漏,但是我得到了不一致的结果。用CComPtr< IInterface > m_interface;
声明指针时
并且在我的C#代码中使用接口没有错误,但是在VC ++中使用接口我得到一个未处理的异常错误,即使我注释掉了IInterface的实例创建。
我很确定问题就在这里:
STDMETHODIMP CSomeClass::get_IClass(IClass** var)
{
return m_class_var->QueryInterface(var);
}
STDMETHODIMP CSomeClass::putref_IClass(IClass* var)
{
m_class_var = var;
return S_OK;
}
当我使用:IInterface* m_interface;
声明接口指针时
在C#中测试接口时出现RPC_E_SERVERFAULT错误,并且必须显式调用GC.Collect()以避免在实例化几个对象后抛出错误。在VC ++中测试接口时,错误是一致的,但是当它发生时是不同的。如果我注释掉IInterface的实例创建,代码运行正常,但是当我尝试创建实例时,我得到的错误与以前一样,只是一个模糊的未处理异常错误。我在这做错了什么?
答案 0 :(得分:2)
CComPtr
是一个智能指针,用于与COM习语一起使用时做“正确”的事情。
get_IClass
的代码看起来不错,但putref_IClass
需要在AddRef
上调用IClass
,因为您要存储它。如果您使用了会自动发生的CComPtr
。
您需要添加有关VC ++未处理异常的更多详细信息。
答案 1 :(得分:1)
IInstance* m_instance
是一个指向IInstance对象的简单指针。您必须自己管理此指针的生命周期。您不像普通对象那样new
和delete
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()
时,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
}
答案 2 :(得分:0)
但是CComPtr&LT; IInterface&gt; m_interface是一个对象。而IInterface * m_interface是一个指针。
第一个会在超出范围时调用它的析构函数,我认为(自从我使用它以来很长时间)它会自动调用m_interface - &gt; Release()。
后者是指向接口的指针,你必须在调用m_interface-&gt; Release()时进行管理。
您可以确认在访问之前没有释放COM对象吗?