I open Matlab engine in an initialization thread, doing :
bool MY_MATLAB_ENGINE_o::Open()
{
// Handle the case where engine is already open
if( MatlabEngine )
{
return true;
}
else if( !( MatlabEngine = engOpen( 0 ) ) )
{
return false;
}
IsEngineOpen.SetValue( true );
return true;
}
Function engOpen()
opens a COM channel to Matlab.
Once the engine is open, the thread falls in wait event mode.
Then, in another thread, I do this :
bool MY_MATLAB_ENGINE_o::ChangeDirectory( QString strPath )
{
QString strPathToScript = "cd('" + strPath + "');";
QByteArray ba = strPathToScript.toLatin1();
const char* cPathToScript = ba.data();
if( MatlabEngine )
{
engEvalString( MatlabEngine, cPathToScript );
return true;
}
return false;
}
I get a CoInitialize has not been called
first-chance exception on engEvalString( MatlabEngine, cPathToScript );
which seems to tell me that Matlab COM server isn't available (but Matlab engine is still up and running).
When I put everything in the same thread it works fine though, but that's not the kind of design I had in mind.
I find Matlab engine documentation lack information about engine+COM. Any idea how to have engine initialization and function calls in separated threads ?
Thanks !
EDIT following RobH's answer
I added this method to my class (instantiated in the second thread) :
bool MY_MATLAB_FUNCTION_CALL_o::PostThreadCreationHook()
{
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr))
{
return false;
}
return true;
}
And now when I call engEvalString( MatlabEngine, cPathToScript );
I get The application called an interface that was marshalled for a different thread
first-chance exception :) I have so much fun this morning ! :)
So, CoMarshalInterface()
?