Встречайте то, что на первый взгляд выглядит как проблема MT, но я пытаюсь подробно понять модель STA, используемую COM +.
По сути, у меня есть устаревший компонент COM +, написанный на VB6, который вызывает собственную (т.е. не-COM) библиотеку Win32 DLL, написанную на C ++.
Имея некоторые проблемы с прерывистым (и невозможно воспроизвести при тестировании), я добавил некоторый код отладки, чтобы выяснить, что происходит, и обнаружил, что при возникновении проблем я чередовал сообщения журнала в файле - так что это подразумевало что DLL вызывается двумя потоками одновременно.
Теперь запись ведется в файл для каждого потока, основанный на _getpid () и GetCurrentThreadId (), поэтому кажется, что когда вызывается код в C ++ DLL, он вызывается дважды в одном и том же потоке одновременно. Мое понимание STA говорит о том, что это может иметь место, так как COM маршаллизирует отдельные экземпляры объектов в одном потоке, приостанавливает и возобновляет выполнение по желанию.
К сожалению, я не уверен, куда идти отсюда. Я читаю, что я должен вызывать CoInitialiseEx () в DllMain (), чтобы сказать COM, что это STA DLL, но в других местах говорят, что это допустимо только для COM DLL и не будет иметь никакого эффекта в нативной DLL. Единственный другой вариант - обернуть части библиотеки DLL в критические секции для сериализации доступа (принимая во внимание любой удар по производительности, который есть у подбородка).
Я мог бы попытаться переработать DLL, но нет общего состояния или глобальных переменных - все находится в локальных переменных, поэтому в теории каждый вызов должен получить свой собственный стек, но мне интересно, имеет ли модель STA какие-то странные Влияет на это и просто повторно входит в уже загруженную DLL в той же точке входа, что и другой вызов. К сожалению, я не знаю, как доказать или проверить эту теорию.
Вопросы в основном:
- Когда компонент STA COM + вызывает собственную DLL, в модели STA нет ничего для
предотвратить приостановку активного "потока" и передачу управления другому "потоку" в середине вызова DLL?
- Является ли CoInitialiseEx () правильным способом решения этой проблемы или нет?
- Если ни (1), ни (2) не являются «хорошими» предположениями, что происходит?