У меня есть элемент управления ActiveX на встроенной HTML-странице IE7 / 8 со следующим событием [id(1)] HRESULT MessageReceived([in] BSTR id, [in] BSTR json)
.В Windows событие регистрируется с OCX.attachEvent("MessageReceived", onMessageReceivedFunc)
.
. Следующий код запускает событие на странице HTML.
HRESULT Fire_MessageReceived(BSTR id, BSTR json)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1] = id;
pvars[0] = json;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars; // -> Memory Corruption here!
return varResult.scode;
}
После того, как я включил gflags.exe с помощью верификатора приложения, следующее странное поведениепроисходит: после Invoke (), который выполняет обратный вызов JavaScript, BSTR из pvars [1] копируется в pvars [0] по неизвестной причине !?Удаление [] из pvars приводит к двойному освобождению той же строки, что приводит к повреждению кучи.
У кого-нибудь есть идея, что здесь происходит?Это ошибка IE или в реализации OCX есть трюк, который мне не хватает?
Если я использую тэг как:
<script for="OCX" event="MessageReceived(id, json)" language="JavaScript" type="text/javascript">
window.onMessageReceivedFunc(windowId, json);
</script>
... странныйОперация копирования не происходит.
Следующий код также выглядит нормально из-за того, что вызывающий Fire_MessageReceived () отвечает за освобождение BSTR.
HRESULT Fire_MessageReceived(BSTR srcWindowId, BSTR json)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
VARIANT pvars[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1].vt = VT_BSTR;
pvars[1].bstrVal = srcWindowId;
pvars[0].vt = VT_BSTR;
pvars[0].bstrVal = json;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.scode;
}
Спасибо!