mshtml завершается ошибкой с FAST_FAIL_INCORRECT_STACK после вызова HideUI

Я написал реализацию IDocHostUIHandler для обеспечения внешнего объекта JavaScript встроенным элементом управления IE11. Один класс предоставляет реализации IUnknown, IDispatch и IDocHostUIHandler. Интерфейс IDispatch возвращается в GetExternal в качестве внешнего объекта.
Все вызовы IDocHostUIHandler, кроме вызова GetExternal в исходный обработчик.

Например HideUI реализован как:

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::HideUI(void)
{
qDebug("Calling HideUI");
if(m_defaultDocHostUIHandler)
{
HRESULT hr = m_defaultDocHostUIHandler->HideUI();
qDebug("Called HideUI");
return hr;
}
return E_NOTIMPL;
}

Тот же шаблон используется для всех других методов, кроме GetExternal, который:

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::GetExternal(IDispatch **ppDispatch)
{
qDebug("Calling GetExternal");
*ppDispatch = (IDispatch*)this;
return S_OK;
}

В JavaScript я выполняю следующее:

var r1 = window.external.Test1();

Это приводит к следующему хвосту отладки:

'2016-10-10 11:09:19'    DEBUG  Calling GetHostInfo
'2016-10-10 11:09:19'    DEBUG  Called GetHostInfo
'2016-10-10 11:09:19'    DEBUG  mtQtWebBrowserDocHandler Release (ref now = 2)
'2016-10-10 11:09:19'    DEBUG  mtQtWebBrowserDocHandler AddRef (ref now = 3)
'2016-10-10 11:09:19'    DEBUG  Calling GetHostInfo
'2016-10-10 11:09:19'    DEBUG  Called GetHostInfo
'2016-10-10 11:09:19'    DEBUG  mtQtWebBrowserDocHandler Release (ref now = 2)
'2016-10-10 11:09:19'    DEBUG  Calling GetExternal
'2016-10-10 11:09:21'    DEBUG  mtQtWebBrowserDocHandler - IDispatch requested
'2016-10-10 11:09:21'    DEBUG  mtQtWebBrowserDocHandler AddRef (ref now = 3)
'2016-10-10 11:09:21'    DEBUG  mtQtWebBrowserDocHandler Release (ref now = 2)
'2016-10-10 11:09:21'    DEBUG  Calling ShowUI
'2016-10-10 11:09:21'    DEBUG  Called ShowUI
'2016-10-10 11:09:21'    DEBUG  Calling HideUI
'2016-10-10 11:09:21'    DEBUG  Called HideUI

Окончательный возврат из HideUI вызывает ошибку INT 29h с ecx = FAST_FAIL_INCORRECT_STACK. Ожидаемый стек 0x18D9C4, а фактический стек 0x18D9A4, расхождение 0x20.

Я полностью озадачен. Другие вызовы моего интерфейса работают правильно, и не имеет никакого значения, если я просто верну E_NOTIMPL из моей реализации HideUI. Что может быть дисбалансом стека?

1

Решение

в GetExternal Функция, вы возвращаете указатель интерфейса без увеличения счетчика ссылок, что приведет к несоответствию счетчика ссылок позже. Лучшая реализация будет:

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::GetExternal(IDispatch **ppDispatch)
{
qDebug("Calling GetExternal");
*ppDispatch = (IDispatch*)this;
this->AddRef();
return S_OK;
}

или использовать QueryInterface там. Если это ATL, InternalQueryInterface, Я подозреваю, что это является причиной вашей ошибки, так как у вас есть ссылка на объект, который, вероятно, был разрушен из-за более Release звонки, чем AddRef звонки.

2

Другие решения

Похоже, ответ заключается в том, что я использовал ICustomDoc в документе браузера, когда mshtml размещался в элементе управления WebBrowser. Это, видимо, не очень хорошая идея! Вместо этого вы должны использовать существующий сайт, предоставленный элементом управления WebBrowser. Я нашел пример правильного способа реализации IDocHostUI здесь https://github.com/FastSpring/FsprgEmbeddedStoreWinMFC и это было чрезвычайно полезно.

0

По вопросам рекламы [email protected]