Internet Explorer выходит из строя при вызове MSXML2::IXMLDOMDocumentPtr -> Release()

StackOverflow https://stackoverflow.com/questions/641896

  •  22-07-2019
  •  | 
  •  

Вопрос

Я создаю расширение оболочки на C ++ (ATL 9) с помощью Visual Studio 2008.Расширение оболочки создает глобальный объект MSXML2::IXMLDOMDocumentPtr m_XmlDoc m_XmlDoc в классе module.Этот m_XmlDoc затем используется в расширении всеми классами для чтения xml-документа.

Проблема, с которой я сталкиваюсь, связана с Internet Explorer.Когда расширение оболочки активно, и я открываю / закрываю Internet Explorer, я получаю диалоговое окно отладки, и IE выходит из строя.В сообщении об ошибке говорится "Необработанное исключение при 0x6aac30f1 в iexplore.exe:0xC0000005:Местоположение чтения с нарушением доступа 0x03050970." Когда я нажимаю "прервать" в окне сообщения, это приводит меня к методу "Release" интеллектуального указателя COM, и ошибка, похоже, связана с m_pInterface-> Release ();

Этот вызов был выполнен из деструктора модуля, и также значение m_pInterface не равно NULL.Я думаю, возможно, Internet Explorer использует XML DOM, и вызов Release создает в нем какую-то проблему.

MSXML2::IXMLDOMDocumentPtr m_XmlDoc;

In _AtlModule.Init() method
    ::CoInitialize(NULL);
    m_XmlDoc.CreateInstance(MSXML2::CLSID_DOMDocument40);

Основной код DllMain:

extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    ::CoInitialize(NULL);
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _AtlModule.Init();  
        CreateImageLists();
        ::DisableThreadLibraryCalls(hInstance);
    }

    hInstance;
    return _AtlModule.DllMain(dwReason, lpReserved); 
}
Это было полезно?

Решение 3

Проблема была из-за COM-указателя COM, используемого для XmlDomDocument. Я изменил его на обычный указатель, и он отлично работает даже в Vista.

Эта проблема имеет другое поведение в XP и Vista. В XP я получал необработанное исключение, когда закрывал Internet Explorer. В Vista мне не удалось просмотреть виртуальный диск.

Другие советы

использование DisableThreadLibraryCalls не рекомендуется, вы видели это?

Есть по крайней мере две проблемы с вашим опубликованным кодом:

  1. Вы вызываете CoInitialize в DllMain.
  2. Вы создаете COM-объект в DllMain.
  3. Меня не удивит, если вы делаете что-то в CreateImageLists(), чего вы также не должны делать в DllMain.

Кроме того, причина, по которой ваш сбой был "исправлен" отказом от использования интеллектуального указателя, заключается в том, что теперь вы фактически больше не освобождаете объект.Ваш код поврежден, и отказ от публикации ссылки не является допустимым способом что-либо исправить.

Я бы посоветовал вам прочитать, а затем перечитывать документацию по ДллМейн уделяя особое внимание вещам, которые вы никогда не должны делать в рамках вашей реализации функции.Как вы увидите прямо сейчас:

Предупреждение Существуют серьезные ограничения на то, что вы можете делать в точке входа DLL.Чтобы обеспечить более сложную инициализацию, создайте процедуру инициализации для библиотеки DLL.Вы можете потребовать, чтобы приложения вызывали процедуру инициализации перед вызовом любых других подпрограмм в библиотеке DLL.

Я подозреваю, что как только вы прочтете это и исправите свой код, чтобы создать COM-объект в допустимое время, и выпустите его в допустимое время, ваше расширение оболочки перестанет сбоить.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top