What is the difference between the two lines of code below:
CComPtr< IInterface > m_interface;
IInterface* m_interface;
I know that CComPtr help eliminate memory leaks, but I am getting inconsistent results. When declaring t开发者_运维百科he pointer with CComPtr< IInterface > m_interface;
and using the interface in my C# code there are no errors, however using the Interface in VC++ I get an unhandled exception error, even if I comment out the instance creation of IInterface.
I am pretty sure the problem is in here somewhere:
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;
}
When I declare the interface pointer with: IInterface* m_interface;
I get a RPC_E_SERVERFAULT error when testing the Interface in C# and have to explicitly call GC.Collect() to avoid the error being thrown after instantiation of a few objects. When testing the Interface in VC++ the error is consistent however when it occurs is different. If I comment out the instance creation of IInterface the code runs fine, however when I try to create an instance I get same error as before, just a vague unhandled exception error. What am I doing wrong here?
CComPtr
is a smart pointer designed to do the 'right' thing when used with COM idioms.
Your code for get_IClass
looks good, but putref_IClass
needs to call AddRef
on the IClass
as you're storing it. If you used CComPtr
that would happen automatically.
You'll need to add more details about your VC++ unhandled exception.
IInstance* m_instance
is a simple pointer to an IInstance object. You have to manage the lifetime of this pointer yourself. You don't new
and delete
COM objects like you would ordinary objects. Instead, the operating system allocates the object when you call the WINAPI function `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;
Each COM object implements reference counting. When the last reference to an object has been Release()
ed, the COM object destroys itself.
Using CComPtr<>
simplifies how you manage the lifetime of the COM objects. It is a smart pointer similar in nature to std::auto_ptr or Boost's shared_ptr, but it works with COM objects. Typically when using a CComPtr you would call the CreateInstance
member function rather than calling the WINAPI function, and you would not explicitly call Release
when you are done. Just let the CComPtr go out of scope, and when it's destructor is called it will call Release
for you:
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
}
CComPtr< IInterface > m_interface is an object. Whereas IInterface* m_interface is a pointer.
The first will have its destructor called when it goes out of scope and I think (a long time since I used it) it will automatically call m_interface ->Release().
The latter is a pointer to an interface and you have to manage when m_interface->Release() is called.
Can you confirm that the COM object is not being released before access?
精彩评论