Builder, CoUninitialize и IXMLDocument в отдельном потоке
От: SterhBy  
Дата: 08.04.05 10:57
Оценка:
Мастера, подскажите.
Есть класс, создаваемый статически, в котором нужно использовать XML parser.
Этот класс используется в отдельном потоке приложения. Это единственный поток, который порождается из основного и выполняет обработку данных.
Выглядит этот класс приблизительно так:

TPayrollParser PayrollParserVar;
TPayrollParser *PayrollParser = &PayrollParserVar;

.............................

class TPayrollParser
{
private:
_di_IXMLDocument x;
public:
__fastcall TPayrollParser(void);
__fastcall ~TPayrollParser();

};
.............................

// Constructor
__fastcall TPayrollParser::TPayrollParser(void)
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
x = NewXMLDocument();
}

// Destructor
__fastcall TPayrollParser::~TPayrollParser()
{
try
{
x->Release();
CoUninitialize(); //Вот здесь ошибка
} catch(...) {}
}
//------------------

Собственно проблема в том, что при вызове CoUninitialize (который вызывается при завершении программы) происходит ошибка, которую нельзя никак перхватить.
Винда выдает:
"Payroll.exe has encountered a problem and needs to close. We are sorry for the inconvenience."

Release практически не влияет на ситуацию.
Если убираю CoUninitialize — все без ошибок.

Приблизительно понимаю, что происходит. Видимо CoUninitialize реально вызывается до уничтожения СОМ-объекта парсера, но не пойму как должно быть правильно.
_di_IXMLDocument — это вроде дельфийский интерфейс и его не нужно удалять вручную.
Когда тогда делать CoUninitialize ?
И можно ли его не вызывать вообще (не повлияет ли это на другие приложения)?

Кстати, вот что пишет Борланд в хелпе:
"There is a situation which could cause crash-on-exit / crash-on-dll-unload problems. This applies if you are writing code that calls CoInitialize in the startup section, and CoUninitialize in the shutdown section. Though Microsoft documentation states that CoInitialize/CoUninitialize must always be called before using OLE code, the reality is that these routines must never be called in DLL startup or shutdown code. CoUninitialize can cause crashes or system deadlocks if called in DLL shutdown code (a unit finalization block)."

Получается, что это мой случай и не нужно вызывать CoUninitialize?

Извините, если вопрос тривиален или я сам себе на него уже ответил, но нужно быть уверенным в том, что решение не повлияет негативно на другие программы, так как работа нескольких программ должна вестись на одной машине в режиме 24х7.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.