Проблема с COM и MSXML (только 64-разрядная версия)

Мы переносим огромное приложение с 32-битного на 64-битное. В этом приложении есть несколько внешних библиотек, которые мы либо отключили, либо использовали их 64-битные версии. Мы также обращаемся к базе данных с помощью наших самописных COM-методов. И мы использовали MSXML4, который отлично работал на 32-разрядных версиях.

64-разрядной версии MSXML4 не существует, поэтому мы обновились до MSXML6. Мы просто используем несколько функций MSXML, особенно парсер DOM, поэтому единственное, что мы сделали, это подставили следующие строки:

#import "msxml6.dll"

и

MSXML2::IXMLDOMDocumentPtr pXMLDocPtr;
pXMLDocPtr.CreateInstance( ___uuidof( MSXML2::DOMDocument60 ) );

затем мы пытаемся сделать что-то вроде этого:

pXMLDocPtr->loadXML( _bstr_t( L"<?xml version=\"1.0\" encoding=\"utf-8\"?><abc></abc>" ) );

Это отлично работает под 32-битной. Но в 64-разрядной версии msxml6.dll выдает исключение при вызове функции loadXML. Хотя CreateInstance возвращает действительный указатель и код возврата S_OK. В выводе отладки также отображается сообщение об ошибке:

First-chance exception at 0x000007fef888238e in App.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
Unhandled exception at 0x000007fef888238e in App.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.

Сначала мы думали, что используем библиотеку неправильно, но потом обнаружили следующее. Если мы прочитаем наш XML-файл до того, как инициализируем наши собственные COM-компоненты, это сработает. Так что теперь похоже, что наши собственные COM-компоненты «повреждают» COM-библиотеку. Но как это вообще возможно?

Мы немного поэкспериментировали, и проблема возникает, только если мы пытаемся использовать MSXML. Все остальные COM-объекты работают. За исключением одного случая, когда IFileDialog (который, я думаю, также является классом COM) разбился во время его использования.

Проблема возникает сразу после того, как мы вызываем CoCreateInstance наших COM-компонентов, что в нашем случае мало что делает. И я не вижу явных ошибок на нашем COM-сервере, например. с 64-битными типами данных.

Итак, вопрос:

Глючит ли 64-битная версия MSXML?

Или мы сделали роковую ошибку с нашим 64-битным портом COM-серверов?

Кто-нибудь сталкивался с подобными проблемами?

Любая помощь будет признательна, так как я действительно застрял в данный момент, потому что я понятия не имею, как отследить реальную проблему.


person Steve Stone    schedule 09.06.2011    source источник
comment
Я также перенес приложение на 64-разрядную версию, и мне пришлось изменить MSXML4 на MSXML6, но не было никаких ошибок при загрузке и анализе XML-документов; библиотека синтаксического анализатора не глючит, по крайней мере, не так, как предлагается. попробуйте создать отдельное простое 64-разрядное приложение, использующее MSXML, и попытайтесь воспроизвести проблему; Я сомневаюсь, что вы сможете; это, вероятно, покажет ошибку в библиотеке.   -  person Marius Bancila    schedule 09.06.2011


Ответы (1)


Типичной причиной этого является неожиданный вызов CoUninitialize() - он приводит к освобождению всех COM-объектов и к тому, что все указатели на них становятся повисшими. см. пример этого вопроса.

person sharptooth    schedule 09.06.2011
comment
Спасибо, но это я уже проверил. Кроме того, если будет вызван CoUninitialize() (по каким-либо причинам), то CreateInstance документа XMLDOMDocument вернет код ошибки. Но вместо этого он возвращает правильный COM-указатель. По крайней мере, похоже. Хотя при первом использовании выдает исключение (как видно выше). - person Steve Stone; 09.06.2011