Приложение с графическим интерфейсом Visual C ++ застряло в режиме MTA
Вопрос
У меня есть проект с графическим интерфейсом C ++, демонстрирующий какое-то странное поведение.На моей машине код компилируется и работает просто отлично.Однако на другой машине код компилируется, но в конечном итоге каким-то образом выполняется в MTA.Очевидно, что нахождение в MTA вызывает всевозможные проблемы во время выполнения графического интерфейса.Вот мой главный:
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew Form1());
return 0;
}
Я могу поставить точку останова в первой строке main, чтобы проверить состояние квартиры, и на машинах, которые строятся / выполняются правильно, это будет "STA", как и ожидалось.Однако на проблемных машинах это будет "MTA".Я даже могу попробовать переключить квартирный режим на STA, но безрезультатно.
Я пытался удалить каталоги debug / release и очистить проект перед компиляцией, запустив его без подключенного отладчика, но все безрезультатно.Я не могу определить какой-либо шаблон, по которому машины работают, а какие нет.Если я скомпилирую exe-файл на рабочей машине и перенесу его на проблемную машину, он будет выполнен корректно, поэтому я подозреваю, что это каким-то образом связано с проблемой среды сборки.Все задействованные компьютеры работают под управлением Windows XP со стандартом Visual Studio 2008.Есть какие-нибудь идеи?
Решение
Разобрался в этом.Наш проект выполнял вызовы библиотеки dll из OpenCV, и эта библиотека dll была скомпилирована для нескольких потоков.Visual Studio заметила это и заставила приложение также скомпилироваться для нескольких потоков.Различные версии библиотеки dll с одного компьютера на другой были ответственны за нерегулярность проблемы.
Другие советы
Я только что закончил исправлять аналогичную ошибку с OpenCV 1.1 и управляемым кодом.По какой-то причине кажется, что библиотеки OpenCV принудительно переводят приложение в MTA (возможно, в COM-объект в интерфейсе OpenCV DShow).Во всяком случае, я нашел это решение:http://www.gamedev.net/community/forums/mod/journal/journal.asp?userid=62708
Если вы повторно инициализируете COM в своем основном приложении, это должно все исправить.Вам нужно будет сослаться на OLE32.lib, чтобы использовать CoUninitialize().Я использовал следующий код:
int main(array<System::String ^> ^args)
{
System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
if (Thread::CurrentThread->GetApartmentState() != ApartmentState::STA)
{
CoUninitialize();
CoInitialize(NULL);
}
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}