Приложение Visual C ++ GUI застряло в режиме MTA - PullRequest
1 голос
/ 30 января 2009

У меня есть проект C ++ GUI, демонстрирующий странное поведение. На моей машине код компилируется и работает просто отлично. Однако на другой машине код компилируется, но в конечном итоге запускается в MTA. Очевидно, что нахождение в MTA вызывает всевозможные проблемы во время выполнения для GUI. Вот мое главное:

        [STAThreadAttribute]
        int main(array<System::String ^> ^args)
        {
            Application::EnableVisualStyles();
            Application::SetCompatibleTextRenderingDefault(false); 
            Application::Run(gcnew Form1());
            return 0;
        }

Я могу поставить точку останова на первой строке main для проверки состояния квартиры, а на машинах, которые правильно строят / выполняют, это будет "STA", как и ожидалось. Однако на проблемных машинах это будет «МТА». Я могу даже попытаться переключить режим квартиры на STA, без эффекта.

Я попытался удалить каталоги debug / release и очистить проект перед компиляцией, запустить без подключенного отладчика, но все безрезультатно. Я не могу определить модель, с которой работают машины, а какие нет. Если я скомпилирую исполняемый файл на работающем компьютере и перенесу его на проблемный компьютер, он будет работать правильно, поэтому я подозреваю, что это как-то проблема среды сборки. Все задействованные машины работают под управлением Windows XP со стандартом Visual Studio 2008. Есть идеи?

Ответы [ 2 ]

1 голос
/ 06 февраля 2009

Разобрался. Наш проект делал вызовы библиотеки DLL из openCV, и эта библиотека была скомпилирована для нескольких потоков. Visual Studio заметила это и вынудила приложение скомпилировать несколько потоков. Разные версии DLL от одной машины к другой были ответственны за нерегулярность проблемы.

0 голосов
/ 02 октября 2009

Я только что закончил исправлять похожую ошибку в 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;
}
...