When dealing with interprocess COM
objects, is it safe to cast a IDispatch*
into an IUnknown*
, without using QueryInterface
?
Here our IDispatch
object comes from an other process OtherProcess.exe
.
And a colleague of mine says that I should call QueryInterface
on the IDispatch
so as to get an IUnknown
.
Currently I'm doing:
void CComThrowDispatch::CheckCOMAvailabilty() const
{
IUnknown * pIUnknown = m_spDispatchDriver.p;
// is this line above a problem ?
// m_spDispatchDriver is an ATL CComDispatchDriver
// it handles an object instanciated in another process.
// m_spDispatchDriver.p is of type IDispatch*
if (pIUnknown == nullptr) return;
bool bComObjectReachable = ::CoIsHandlerConnected(pIUnknown) == TRUE;
if (bComObjectReachable == false)
{
throw MyException;
}
}
My problem with his suggestion: I am dealing with cases (access violations) when the OtherProcess.exe has crashed or has been killed. It seems calling any functions like Invoke
on the IDispatch
that encapsulates any objects from this no longer exisiting OtherProcess.exe provokes these access violations (EDIT: comments and answers reveals that this latest assumption was completely false!).
That's why I'm trying to protect the application testing ::CoIsHandlerConnected(pIUnknown);
which takes an IUnknown
as parameter.
But by calling QueryInterface
on the IDispatch
, like my colleague advises me to do, I am afraid to fall back in the same problem I am trying to solve: This IDispatch
handles an object that no longer exists, and QueryInterface
to an IUnknown
would just be Undefined Behaviour all the same (EDIT again, this assumption is also false).
Am I really wrong when I just do the cast ?
What is the common way to deal with dead interprocess COM
objects ?
This is the begining of the definition of IDispatch
in OAIdl.h, which is declared as deriving from IUnknown
.
MIDL_INTERFACE("00020400-0000-0000-C000-000000000046")
IDispatch : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ __RPC__out UINT *pctinfo) = 0;