Имея дело с interprocess COM
объектов, безопасно ли лить IDispatch*
в IUnknown*
, без использования QueryInterface
?Можно ли лишить IDispatch * в IUnknown * без использования QueryInterface для межпроцессных COM-объектов?
Здесь наш объект IDispatch
происходит от другого процесса OtherProcess.exe
. И мой коллега говорит, что я должен позвонить QueryInterface
на номер IDispatch
, чтобы получить IUnknown
.
В настоящее время я делаю:
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;
}
}
Моей проблему с его предложением: Я имею дело со случаями (нарушения доступа), когда OtherProcess.exe испорчены или был убит. Кажется, что вызов Invoke
на IDispatch
, который инкапсулирует любые объекты из этого более не существующего файла OtherProcess.exe, вызывает эти нарушения доступа (EDIT: комментарии и ответы показывают, что это последнее предположение было полностью ложным!).
Именно поэтому я пытаюсь защитить тестирование приложения ::CoIsHandlerConnected(pIUnknown);
, которое принимает параметр IUnknown
.
Но по телефону QueryInterface
на IDispatch
, как мой коллега советует мне делать, я боюсь упасть обратно в той же проблеме, я пытаюсь решить: Этот IDispatch
обрабатывает объект, который больше не существует, и QueryInterface
к IUnknown
будет просто неопределенным Поведение все равно (EDIT опять же это предположение также неверно).
Я действительно ошибаюсь, когда я просто делаю актеры? Каков общий способ борьбы с мертвым межпроцессом COM
объектов?
Это начало определения IDispatch
в OAIdl.h, которое объявляется как результат от IUnknown
.
MIDL_INTERFACE("00020400-0000-0000-C000-000000000046")
IDispatch : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ __RPC__out UINT *pctinfo) = 0;
* На самом деле * неправильно использовать. Вызов метода на интерфейсе с мертвого сервера вызывает ошибку RPC, а не AVE. Вам нужно получить RPC_E_SERVERDIED. Вам нужно сосредоточиться на реальной проблеме здесь, прямо сейчас вы просто делаете это хуже. –
@ HansPassant Это интересно, спасибо. Однако мне трудно понять, почему это * действительно неправильно * для ** upcast ** IDispatch, который происходит из IUnknown, в IUnknown. Не могли бы вы рассказать об этом? Какова первоначальная ошибка, которую я делаю? –
@StephaneRolland: В некоторых случаях вам нужно/нужно запрашивать «IUnknown», даже если какой-либо интерфейс получен из него и доступен ли он доступен (см. Раздел [Объекты должны иметь идентификаторы] »(https://msdn.microsoft.com/en-us /library/windows/desktop/ms686590%28v=vs.85%29.aspx)), однако это не так в вашем вопросе. –