views:

365

answers:

2

I've got a C++ gui project exhibiting some strange behavior. On my machine, the code compiles and runs just fine. However, on another machine, The code compiles but ends up running in MTA somehow. Obviously, being in MTA causes all sorts of runtime problems for the GUI. Here is my main:

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

I can put a breakpoint on the first line of main to check the apartment state, and on the machines that build/execute correctly, it will be "STA", as expected. However, on the problematic machines, it will be "MTA". I can even try switching the apartment mode to STA, without effect.

I've tried removing the debug/release dirs and cleaning the project before compiling, running without a debugger attached, all to no avail. I can't determine any pattern to which machines work and which do not. If I compile the exe on a working machine and bring it over to a problematic machine, it will execute correctly, so I suspect this is somehow a build environment issue. All machines involved are running windows XP with visual studio 2008 standard. Any ideas?

A: 

Figured it out. Our project was making calls to a dll from openCV, and that dll had been compiled for multiple threads. Visual studio noticed this and forced the app to compile for multiple threads as well. Differing versions of the dll from one machine to another were responsible for the irregularity of the problem.

A: 

I just got done fixing a similar bug with OpenCV 1.1 and managed code. For some reason it seems that the OpenCV libraries force the application into MTA (perhaps a COM object in the OpenCV DShow interface). Anyway I found this solution: http://www.gamedev.net/community/forums/mod/journal/journal.asp?userid=62708

If you re-initialize COM in your main application it should fix everything. You will need to link to OLE32.lib to use CoUninitialize(). I used the following code:

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;
}
kscottz