My third party application has an ability similar to the DOS or SYSTEM functions in MATLAB: it can call an other application and capture the results. Through this ability I want to call MATLAB in batch mode, when I do this I want to be able to capture the output which is normally displayed in the Command Window. It appears however that MATLAB does not write this output to stdout and thus cannot be captured by my third party application. Is there another way to do this?
MATLAB: How to redirect the Command Window output to stdout and stderr when running MATLAB 7.8 (R2009a) in batch mode
MATLAB
Related Solutions
This happens starting from MATLAB (7.14) R2012a onwards, where Environment variables for the three data streams STDIN, STDOUT and STDERR were set to -1.
To work around the issue, you may wrap your SYSTEM call which executes a FORTRAN script as follows:
setenv(‘GFORTRAN_STDIN_UNIT’, ‘5’)setenv(‘GFORTRAN_STDOUT_UNIT’, ‘6’)setenv(‘GFORTRAN_STDERR_UNIT’, ‘0’)system(‘myFortranScript’, ‘-echo’)%This resets the environment variables back to default values of -1.
setenv(‘GFORTRAN_STDIN_UNIT’, ‘-1’)setenv(‘GFORTRAN_STDOUT_UNIT’, ‘-1’)setenv(‘GFORTRAN_STDERR_UNIT’, ‘-1’)
In any program, there are three reserved streams that the program can read from and write to.
‘stdin’ is generally what is used as the input stream, such as when a program asks you to type something on the keyboard.
‘stdout’ is generally what is used as the output stream, such as when you use the WRITE function in FORTRAN.
‘stderr’ is generally what is used as the error stream, which is where a program will write the issues it is encountering, so that a developer or debugger can differentiate between output that is supposed to be seen and errors in the program that are discovered.
GFORTRAN-compiled programs attempt to open these three streams, and then unconditionally close them when they are finished. However, this is an issue for programs like MATLAB which interferes with the input and output of user processes which also read to and write from ‘stdin’, ‘stdout’, and ‘stderr’.
Therefore, from MATLAB (7.14) R2012a onwards, these three environment variables are set to -1 by default. Setting this to -1 will ensure that MATLAB has control over these streams, thereby allowing it to function correctly. While running a FORTRAN program which needs this access from within MATLAB, these changes have to be made temporarily.
When these variables are set to -1, note that MATLAB will not read from the ‘stdout’ and ‘stderr’ streams the FORTRAN script expects to write to, and it will not write to the ‘stdin’ stream the script expects to read from. This will cause the output of the program to not be captured in the command window.
MATLAB: How to capture error messages when working with MATLAB Engine when using MATLAB 7.8 (R2009a)
MATLAB 7.8 (R2009a) directs any error messages to STDERR by default. To be able to capture the error messages in the output buffer, all errors occurring in the MATLAB code must be trapped and prevented from being directed to STDERR. In MATLAB, this can be accomplished by placing the code within a TRY-CATCH statement. The code snippet below indicates how this can be implemented in MATLAB:
try thisiswrongcatch ex disp(ex.message) % The disp command outputs to stdout
end
In the C-code, you can create a wrapper function which automatically places all the commands to be executed within TRY-CATCH statements before evaluating the expression on the MATLAB Engine. The code below indicates how this can be implemented:
int doEval(Engine* en, char *com) { /* Buffer in which we are going to add the try catch statement */ char buffer[BUFFERSIZE]; /* Wrap the original command in: * try * OriginalCommand * catch ex * disp(ex.message) * end */ sprintf(buffer,"try,%s,catch ex,disp(ex.message);end",com); /* Call the wrapped command */ return engEvalString(en, buffer); }int main(int argc, char *argv[]) { Engine *en; int res; char buffer[BUFFERSIZE]; /* Open connection to MATLAB */ en = engOpen(NULL); /* Define that Command Window output should be written to buffer */ engOutputBuffer(en, buffer, BUFFERSIZE); /* Don't call engEvalString directly, instead use the doEval wrapper which wraps to command in a TRY-CATCH statement */ res = doEval(en, "thisiswrong"); printf("Output: %s\n",buffer); /* Close the engine */ engClose(en);}
Best Answer