|

Introduction
Matlab(c) is a well-known scientific software covering a wide range of engineering and mathematicals fields.
It contains also a set of complete and powerfull visualization tools.
Matlab(c) contains it's own language and you can easily develop applications on it. However, sometimes you will
want to run it from a C/C++ application and that's where everything get's tricky. In fact, although Matlab(c) comes with
a C API, it is complicated to use: linking problems, compiler special flags and other mysterious bugs (maybe I did it all wrong).
Another solution is to use the COM interface of the ActiveX control. The sad thing about this interface is that... it's COM and you end up with dozens of lines of code... That's where the CMatlabEngine gets in the play. It hides all the COM code (getting CLSID, getting IDispatch, allocating variants, setting function arguments and many others) and enables you to focus on the main part of the job: use Matlab(c).
This article will discuss the main features the class, for further details check the Doxygen documentation
that is shipped with the demo project. Note that you can also generate it by running Doxygen on MatlabEngine.h
Initializing the engine
All the initialization code is contained in the constructor of CMatlabEngine. You can check
that the server has been correctly initialized by calling IsInitialized:
CoInitialize(NULL);
...
CMatlabEngine mt;
if (!mt.IsInitialized())
Do not forget to uninitialize COM when quitting the application:
CoUninitialize();
Engine main methods
The matlab engine contains 5 main methods: Execute, PutMatrix, GetMatrix, PutString and GetString
Executing Matlab(c) code:
You can execute Matlab(c) code by calling Execute( LPCTSTR szMatlabCode ):
mt.Execute(_T("surf(peaks)"));
mt.Execute(_T("title('demo')"));
Sending arrays to Matlab(c)
You can send array, real or complex, in the form of vector to Matlab(c) by using PutMatrix.Note that the vector in PutMatrix have to be ordered line by lines: for a matrix M of size (mxn), M(i,j) is equivalent to M[i* n + j].
UINT nRows=10;
UINT nCols=2;
vector<double> v( nRows * nCols );
...
mt.PutMatrix( _T("M"), v, nRows, nCols);
Retreiving arrays from matlab
You can retreive arrays (real or complex) by calling GetMatrix( It is the dual of PutMatrix):
mt.Execute(_T("v=[1 2 3; 4 5 6]';"));
vector<double> vReal;
UINT nRows, nCols;
mt.GetMatrix(_T("v"), nRows, nCols, vReal);
nRows and nCols now contains the dimension of the array and vReal the data.
Sending string to Matlab(c)
Piece of cake using PutString:
mt.PutString("text", "Inserting a string named text");
Getting string from Matlab(c)
Use the method GetString:
LPTSTR szText;
mt.GetString("myText",szText);
Note that szText is allocated on the heap by GetString, the memory cleaning is left to the user.
Workspace
You can modify the workspace you are working on by using SetWorkspace. By default, the workspace is
"base". If you want to declare global variables, use "global" workspace.
Handling the Matlab Window state
- Minimize the command window,
mt.MinimizeWindow();
- Maximize the command window,
mt.MaximizeWindow();
- Show, hide the command window,
mt.Show( true );
- Get the visibility state the command window,
if(mt.IsVisivle())
- Quit the command window,
mt.Quit();
Known bugs and limitations
Matlab 5.3 and earlier
Some function interface from the Matlab engine have been introduced only with the version 6.0 therefore user with version earlier than 6.0 would have faced problem with the class.
If you have a Matlab earlier than v6.0, undefine the MATLAB_VERSION_6 constant that is at the beginning of MatlabEngine.h, it will disable the following functions:
IsVisible, Show, PutString, GetString
Further developments
- Write
PutCellArray and GetCellArray to write and read cell arrays.
Reference and further reading
Revision History
| 21-10-2002 | Added references |
| 10-09-2002 |
GetString is now working! At last !
- Fixed bugs in
GetResult, GetMatrix
thanks to Juan Carlos Cobas.
|
| 09-25-2002 |
GetMatrix is now working! At last !
|
| 09-23-2002 |
- Added
PutString method
- Added MATLAB_VERSION_6 string for Matlab version < 6. Thanks for ZHANG Yan for finding the workaround.
|
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 73 (Total in Forum: 73) (Refresh) | FirstPrevNext |
|
 |
|
|
Hello, I'm using MatlabEngine, and it works fine, except the PutMatrix() method!
When I execute in VS:
matlab_obj.PutMatrix(_T("M"), v, nRows, nCols);
In Matlab command window I make:
>>whos
and the workspace is empty!!!
I'm using Matlab 7.0!!
Can anyone help-me??
sérgio
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
for clueless idiots like me:
VERY simple instructions:
a) in MATLAB create an m file containing the script (code) you want to run. save it as 'C:\\MATLAB6p5\\work\\test'
b) in VC++ 1) create an new win32 cosole aplication under File>NEW>project (win32 = normal windows) and select "a simple application"
2) copy MatlabEngine.cpp and MatlabEngine.h to the newly created folder (where you instructed C++ to build the project)
3) copy the stdafx.h contents to your newly created stdafx.h file (not the .ccp)
4) add MatlabEngine.cpp to your source files
5) in your main cpp window (your main program) delete all sample text and replace with this:
#include "stdafx.h" #include "MatlabEngine.h"
int main(int argc, char* argv[]) { CoInitialize(NULL);
CMatlabEngine mt;
mt.Execute(_T("run 'C:\\MATLAB6p5\\work\\test')"));
CoUninitialize(); }
It worked for me. I hope it works for you as well
Thanos
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello,
I need to use some commands from Matlab 7 in c++ builder 5, I'm including the libraries "MatlabEng.h" and "MatlabEng.c", but this libraries use matlab.h and engine.h and I don't have this, what can I do? Somebody have and example to use Matlab with builder?.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I used this excellent class a couple of years ago, to connect a program to matlab 6. I tried using matlab 7 with my original program, and the connectivity no longer works. Does anyone know if matlab 7 no longer supports COM, or what changes must be made for this version? Thanks, - Arnon
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I figured this one out from the matlab help. You can start the COM server by adding the /Automation switch to the matlab shortcut.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I would really appreciate it if you could give me the details on how to make this class wrapper Matlab 7 compatible. I don't know in which part of the class wrapper I have to add add the /Automatioon switch.
Thanking advance for your help, best regards Rdiaz
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hi,
I found a workaround for this... I changed the loading string in the CMatlabEngine.cpp to:
CLSID clsid; if (bDedicated) m_hr=::CLSIDFromProgID(OLESTR("Matlab.Application.Single.7"), &clsid); else m_hr=::CLSIDFromProgID(OLESTR("Matlab.Application.7"), &clsid); if (FAILED(m_hr)) return;
It's working on my side! RD
|
| Sign In·View Thread·PermaLink | 3.50/5 (2 votes) |
|
|
|
 |
|
|
Hi, I'm calling the function SetMatrix(..) with vector that contain 3x3 matrix with the values: 1,2,3,4,5,6,7,8,9. But the line after I called SetMatrix(..), I call the function GetMatrix(..). The vector that I get contains the values: 1,4,7,2,5,8,3,6,9. I other word the rows and the columns are replaced.
Any idea why? Thanks, Gal
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
sir thank u for u r responce just iam using matlab as addin
i wrote some m file and iam adding that to my mfc application when i add some more files it is throwing this error iam copied output window appwizard this is message -------------------Configuration: MyDigFil - Win32 Debug-------------------- Performing Custom Build Step on "D:\MyDigFil\MyCheby1Bp.m" Error: "codege" is not a valid -T option argument. Compiler version: 3.0 Error: The options specified will not generate any output files. Please use one of the following options to generate an executable output file: -x (generates a MEX-file executable using C) -m (generates a stand-alone executable using C) -p (generates a stand-alone executable using C++) -S (generates a Simulink MEX S-function using C) -B sgl (generates a stand-alone graphics library executable using C (requires the SGL)) -B sglcpp (generates a stand-alone graphics library executable using C++ (requires the SGL)) -B pcode (generates a MATLAB P-code file) Or type mcc -? for more usage information. Error executing c:\winnt\system32\cmd.exe.
MyDigFil.exe - 2 error(s), 0 warning(s) thank u very mush ir if u don't if u have any fir filter any filter with mfc pls send me it's very urgent for me.iam new to matalab and no time to read full math work and design so if u don't mind pls one fir filter using vc++ code i need .
thank u very much have a nice day
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
sir when iam using matlab in vc++ it is throwing this error iam new to matlab so i am unable to find why this error is coming when i compile it is giving this Performing Custom Build Step on "e:\matlab6p5\toolbox\signal\signal\cheb2ap.m" Error: "codege" is not a valid -T option argument. Error executing c:\winnt\system32\cmd.exe.
MyDigFil.exe - 1 error(s), 0 warning(s)
kindly suggest me solution have anice day
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sir,
I don't understand this error message. You should not be compiling .m files using the MatlabEngine ??? Are you trying to do .mex files ?
ps: Please encapsulate your error message in pre tags and do a full cut-and-paste of the compilation log!
Jonathan de Halleux. www.dotnetwiki.org
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello! I'm soo happy there is code to make it able to run Matlab from C++.
I'm having a camera with a C++ program. I need to do things to my camera-images and find it easiest to do it in Matlab. So I've understood that in my C++ code I could just add the MatlabEngine.h and .cpp -files (and StdAfx files) to my project, include MatlabEngine.h to my C++ code, initialize and unitialize the engine and inbetween perform whatever I like to perform, correct?
My problem is that if I only do CoInitialize(NULL), then Matlab doesn't get initialized, so if I add "mt=new CMatlabEngine;" then my program warns me saying that I bool to false or true, but I can run the program, just not perform anything if I would like to. What can I have missed? [ONE HOUR LATER: I took out CoInitialize(NULL) and now I could run PutString(). So is it good enough just having "mt=new CMatlabEngine;" to initialize Matlab?]
I can run the demo without problems, BUT you have written "/TODO: Place code here" in int APIENTRY WinMain(..) in the MatlabEngineDemo.cpp file, and I understood that line as to write some code afterwards, and I tried it, but with no results at all. I added the three lines for PutString as you have later on. What's the meaning here? should I add code or not and what kind of code could I add?
Merci bcp
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
astridwahlin wrote: [ONE HOUR LATER: I took out CoInitialize(NULL) and now I could run PutString(). So is it good enough just having "mt=new CMatlabEngine;" to initialize Matlab?]
This should be sufficient. You don't need to call CoInitialize(NULL) if the COM interface is already initialized. Note that are not obliged to allocated dynamically CMatlabEngine.
astridwahlin wrote: "/TODO: Place code here"
This is generated by the MFC wizard. You should modify the code at this point but add new code in the WndProc function. Don't bother about modifying the demo version (which is for demonstration), I advise you to create a new console application and start from scratch: create an empty console project, follow the article for that.
Jonathan de Halleux. www.dotnetwiki.org
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I integrated this class into a simulator that makes many calls to the CMatlabEngine::Execute() function. Memory usage of the program increased tremendously. I think that this is caused by m_vResult, which gets the return value from matlab. This variable is also used in IsVisible() and GetString(). Must it be explicitly freed before reusing (I'm not too familiar with VARIANT types)?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is what I did to solve the memory leaks, but I haven't debugged this much to see if it causes any damage:
In MatlabEngine.h, I added a protected method:
//! Free memory that was allocated for the result member: void FreeResult();
In MatlabEngine.cpp I made the following changes: In the constructor, added:
m_vResult.bstrVal = NULL;
Before every call to
m_pMtlbDispApp ->Invoke(..., &m_vResult, ...)
(there are three such calls, in Execute(), IsVisible() and GetString()) I added:
FreeResult();
At the end of the file I added:
void CMatlabEngine::FreeResult() { if (m_vResult.vt == VT_BSTR) { ::SysFreeString(m_vResult.bstrVal); m_vResult.bstrVal = NULL; } }
I would be happy to hear any remarks - if there is anything else that must be checked before freeing the result, or if there is anything else to initialize.
Hope this helps more than it hurts, - Arnon
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
It seems like there are two small bugs in the error handler: 1. ::_tprintf should be ::_stprintf (lines 136 and 155), otherwise, the error strings errMsg and extMess are left as garbage. 2. errDesc is used without being set (line 138). Where can you find the description of the error message?
Thanks, - Arnon
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I made some changes to the error handler so that I could see a description of the MATLAB errors that I get. Here is my modified version of ErrHandler:
void CMatlabEngine::ErrHandler(HRESULT hr, EXCEPINFO excep, UINT uArgErr) { // Allow converting BSTR to normal strings: USES_CONVERSION;
if (hr == DISP_E_EXCEPTION) { TCHAR errMsg[512];
::_stprintf(errMsg, TEXT("Run-time error %d:\n\n %s"), excep.scode & 0x0000FFFF, //Lower 16-bits of SCODE OLE2T(excep.bstrDescription)); //Text error description ::MessageBox(NULL, errMsg, TEXT("MATLAB Error"), MB_SETFOREGROUND | MB_OK); } else { LPVOID lpMsgBuf; ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf, 0, NULL); if ((hr == DISP_E_TYPEMISMATCH ) || (hr == DISP_E_PARAMNOTFOUND)) { TCHAR extMess[512]; ::_stprintf(extMess, TEXT("%s Position of incorrect argument is %u.\n"), (LPCTSTR) lpMsgBuf, uArgErr); ::MessageBox(NULL, extMess, TEXT("COM Error"), MB_OK | MB_SETFOREGROUND); } else { ::MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("COM Error"),MB_OK | MB_SETFOREGROUND); } ::LocalFree(lpMsgBuf); } }
You must also add the following line to MatlabEngine.cpp:
#include <atlbase.h> // Allows converting BSTR to normal strings
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Thank you for the fix. I'll post an update of the source but it will take time to get to CP.
Jonathan de Halleux.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks for this simple and very useful class. The beautifully formatted doxygen documentation could be used as a reference for most programmers to learn from...
One small issue and one question: In the article, you recommend checking IsInitialized() after instantiating the class, but you don't do this in the demo code. 
And for the question: We have a limited number of licenses at work. When you open matlab but can't get a license, you get a fatal error message box, and after you close it, matlab closes. Unfortunately, IsInitialized() returns true even when a license wasn't acquired. Is there any way to make sure that the app was really opened?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is what I added to the demo code in InitInstance:
glob_pMatlab = new CMatlabEngine; if (!glob_pMatlab->IsInitialized()) { ::MessageBox(NULL,"Can't initialize MATLAB","Fatal Error!",MB_OK); return FALSE; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thks (don't forget to vote ) arnonm wrote: In the article, you recommend checking IsInitialized() after instantiating the class, but you don't do this in the demo code.
In fact, I'll fix that in the next release. Anyway, all methods of the wrapper check if it is initialized too...
arnonm wrote: We have a limited number of licenses at work. When you open matlab but can't get a license, you get a fatal error message box, and after you close it, matlab closes. Unfortunately, IsInitialized() returns true even when a license wasn't acquired. Is there any way to make sure that the app was really opened?
You too... This damn software is not cheap and has a "very" dominant position on the math field. I'm not very much into COM now... The key of the problem is "how to know if Matlab is open or not ???"
Anybody an idea?
Jonathan de Halleux.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Is the sample available in C#?
This sample works, but when I add the Reference in a Project and call mlapp.Execute("..."); I get the exception QueryInterface for interface MLapp.DIMLapp failed.
Why?
Laszlo Sragner
|
| Sign In·View Thread·PermaLink | 4.25/5 (3 votes) |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|