|

Introduction
In two past articles (Solving Engineering Problems Using MATLAB C API and Solving Engineering Problems Using MATLAB C++ Math Library), I show you how can a programmer develop an application that using MATLAB features like computing complex engineering problems. But if you are not familiar with MATLAB APIs or MATLAB C++ interface or these are hard coding techniques, this article is for you.
MATLAB Engine
MATLAB provides some API functions for controlling it. These APIs required that you installed MATLAB on your target machine. We named these APIs, MATLAB Engine API. For an alternative method, you can use MATLAB ActiveX control. For more information refer to article: A class wrapper for Matlab (C) ActiveX Control by Jonathan de Halleux.
Using MATLAB Engine
For using MATLAB engine, you must follow these steps:
- Add matlab.h interface file to stdafx.h or any desired interface/implementation file.
- Add MATLAB libraries to your project. For this reason, we need these libraries: libeng.lib, libmx.lib, libmatlb.lib, libmat.lib, libmmfile.lib.
- Add MatlabEng.h and MatlabEng.cpp files to your project.
- Declare a variable with type of
CMatlabEng. (Remember to include MatlabEng.h interface file).
- Use member functions of
CMatlabEng class, to control MATLAB and send commands to it and retrieve computed values or plotted graphs!
- Compile your project.
CMatlabEng
Following codes are definition of CMatlabEng class. It's very simple to use. class CMatlabEng {
public:
int OutputBuffer(char *p, int n);
void OpenSingleUse(const char *startcmd, void *dcom, int *retstatus);
int GetVisible(bool* value);
int SetVisible(bool value); mxArray* GetVariable(const char* name);
int PutVariable(const char *name, const mxArray *mp);
int EvalString(const char* string);
void Open(const char* StartCmd); int Close(); CMatlabEng();
virtual ~CMatlabEng();
protected:
Engine* pEng;
};
CMatlabEng in detail
Table 1 is a complete reference of member functions of CMatlabEng class.
| Member Function |
Description |
int OutputBuffer(char *p, int n); |
OutputBuffer defines a character buffer for EvalString to return any output that ordinarily appears on the screen. The default behavior of EvalString is to discard any standard output caused by the command it is executing. OutputBuffer (p,n) tells any subsequent calls to EvalString to save the first n characters of output in the character buffer pointed to by p. To turn off output buffering, use OutputBuffer(ep,NULL,0); |
void OpenSingleUse (const char *startcmd, void *dcom, int *retstatus); |
This routine allows you to start multiple MATLAB processes for the purpose of using MATLAB as a computational engine. OpenSingleUse starts a MATLAB process, establishes a connection, and returns a unique engine identifier, or NULL if the open fails. OpenSingleUse starts a new MATLAB process each time it is called. OpenSingleUse opens a COM channel to MATLAB. This starts the MATLAB that was registered during installation. If you did not register during installation, on the command line you can enter the command: matlab /regserver
OpenSingleUse allows single-use instances of a MATLAB engine server. OpenSingleUse differs from Open, which allows multiple users to use the same MATLAB engine server. |
int GetVisible (bool* value); |
Returns status of the window for the MATLAB engine session, is visible or invisible on the Windows desktop. |
int SetVisible (bool value); |
SetVisible makes the window for the MATLAB engine session, either visible or invisible on the Windows desktop. You can use this function to enable or disable user interaction with the MATLAB engine session. |
mxArray* GetVariable (const char* name); |
Reads the named mxArray from the MATLAB engine session associated with ep and returns a pointer to a newly allocated mxArray structure, or NULL if the attempt fails. GetVariable fails if the named variable does not exist. Be careful in your code to free the mxArray created by this routine when you are finished with it. |
int PutVariable (const char *name, const mxArray *mp); |
PutVariable writes mxArray mp to the engine ep, giving it the variable name, name. If the mxArray does not exist in the workspace, it is created. If an mxArray with the same name already exists in the workspace, the existing mxArray is replaced with the new mxArray. |
int EvalString (const char* string); |
Evaluates the expression contained in string for the MATLAB engine session, previously started by Open. |
void Open (const char* StartCmd); |
This routine allows you to start a MATLAB process for the purpose of using MATLAB as a computational engine. |
int Close(); |
This routine allows you to quit a MATLAB engine session. |
Sample Program
Following program is a sample that uses CMatlabEng class. Program logic is very simple.
#include "stdafx.h"
#include "MatlabEng.h"
#define message(x) printf(x"\n\n")
int main(int argc, char* argv[])
{
CMatlabEng matlab;
message("Starting MATLAB");
matlab.Open(NULL);
message("Hiding MATLAB");
matlab.SetVisible(FALSE);
message("Press any key to continue");
getch();
message("Showing MATLAB");
matlab.SetVisible(TRUE);
message("Press any key to continue");
getch();
mxArray *T = NULL;
double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
T = mxCreateDoubleMatrix(1, 10, mxREAL);
memcpy((void *)mxGetPr(T), (void *)time, sizeof(time));
message("Send matrix T to matlab");
matlab.PutVariable("T", T);
matlab.EvalString("D = .5.*(-9.8).*T.^2;");
message("Plot(T, D)");
matlab.EvalString("plot(T,D);");
matlab.EvalString("title('Position vs. Time for a falling object');");
matlab.EvalString("xlabel('Time (seconds)');");
matlab.EvalString("ylabel('Position (meters)');");
matlab.EvalString("grid;");
message("Press any key to continue");
getch();
mxDestroyArray(T);
message("Showing MATLAB graphics capabilities");
matlab.EvalString("z=peaks(25);");
matlab.EvalString("surf(z);");
matlab.EvalString("colormap(jet);");
matlab.EvalString("knot;");
getch();
matlab.Close();
return 0;
}
Enjoy!
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 173 (Total in Forum: 173) (Refresh) | FirstPrevNext |
|
|
 |
|
|
I'm running Visual Studio 8 and Matlab 7, now I've changed matlab.h to matrix.h, which allows it to compile properly, however when it tries to build it can't open "libmatlb.lib". As I understand it MatLab 7 doesn't require libmatlb.lib or libmmfile.lib, but when I take out the code that tries calling them I get 8 more build errors:
Matlab to C++.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CMatlabEng::~CMatlabEng(void)" (??1CMatlabEng@@UAE@XZ) Matlab to C++.obj : error LNK2001: unresolved external symbol "public: int __thiscall CMatlabEng::Close(void)" (?Close@CMatlabEng@@QAEHXZ) Matlab to C++.obj : error LNK2001: unresolved external symbol "public: int __thiscall CMatlabEng::EvalString(char const *)" (?EvalString@CMatlabEng@@QAEHPBD@Z) Matlab to C++.obj : error LNK2001: unresolved external symbol "public: int __thiscall CMatlabEng::PutVariable(char const *,struct mxArray_tag const *)" (?PutVariable@CMatlabEng@@QAEHPBDPBUmxArray_tag@@@Z) Matlab to C++.obj : error LNK2001: unresolved external symbol "public: int __thiscall CMatlabEng::SetVisible(bool)" (?SetVisible@CMatlabEng@@QAEH_N@Z) Matlab to C++.obj : error LNK2001: unresolved external symbol "public: void __thiscall CMatlabEng::Open(char const *)" (?Open@CMatlabEng@@QAEXPBD@Z) Matlab to C++.obj : error LNK2001: unresolved external symbol "public: __thiscall CMatlabEng::CMatlabEng(void)" (??0CMatlabEng@@QAE@XZ) Debug/Matlab to C++.exe : fatal error LNK1120: 7 unresolved externals Error executing link.exe.
Any ideas on how to get over this obstacle?
thanks for your time
TNT
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
hi, i have read the article about how to use matlab syntax in c++, but i cant understand it(maybe its because my english is not good enough). actually, i want to do singular value decomposition(svd) function from matlab to my c++ project because i dont want to waste time to make the function myself..(actually i need some functions, not only svd)
anyone can tell me step by step how to use/connect matlab in c++? u can send me an email to rifsolution@yahoo.com
please help me.. thanx..
btw, i use matlab 5.3, msvc++ 6.0, windows vista
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Dir Sir, I use Microsoft Visual Studio.NET, Matlab 6.5. I tried to use header flie "engine.h", but I meet the below problem:
This is my code: ----------------- #include #include
#include "engine.h"
void main() { Engine* ep; ep = engOpen(NULL); // Connect to MATLAB engine ------------------
When I build project, I have the error:
error LNK2019: unresolved external symbol engOpen referenced in function_main
I look forward to hearing from you. Thanks you so much. Best regards,
|
| Sign In·View Thread·PermaLink | 1.75/5 (4 votes) |
|
|
|
 |
|
|
Hi,
I have tried to run this code in visual studio 2005. I have changed Matlab.h to matrix.h, removed the unnecessary libs and the program compiles without error. However, at runtime I get an unhandled exception and a crash in gs_support.c in the lines listed below
#else /* defined (_WIN64) */ cookie = systime.ft_struct.dwLowDateTime; cookie ^= systime.ft_struct.dwHighDateTime; #endif /* defined (_WIN64) */
Please find error log below
'MatlabClass.exe': Loaded 'C:\Documents and Settings\mdp28\Desktop\MatlabEng_demo\Debug\MatlabClass.exe', Symbols loaded. 'MatlabClass.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded. 'MatlabClass.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded. First-chance exception at 0x000a4ad6 in MatlabClass.exe: 0xC0000005: Access violation reading location 0x000a4ad6. Unhandled exception at 0x000a4ad6 in MatlabClass.exe: 0xC0000005: Access violation reading location 0x000a4ad6. The program '[3800] MatlabClass.exe: Native' has exited with code 0 (0x0).
Regards Michael
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
|
Hi, at first thanks for writing CMatlabEng. I want to use an instance 'm_matlab' of CMatlabEng as a member in another class. I wanted to open the Instance in the constructor (m_matlab.Open(NULL) and close it in destructor. I found out that it only works when Opening 'm_matlab' in the same method where I want to use it. Do you have some idea what´s the reason for this? thanks in advance Jower
-jower
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello!
Sounds familiar ... It seems the matlab engine can only be used within the same thread it's been initialized in. If your constructor is called within thread A and your actual data processing is done in another thread B, it won't work. (Check "GetCurrentThreadId()")
Its no solution but that's what I've figured out by now.
Best regards Sven
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I am using the MATLAB v7.0.0(R14)and changed "Matlab.h" to "Matrix.h".
But, when I have complied the "MatlabClass", I got the error message "cannot open file "libeng.lib" ".
Do I have to set the full path of "libeng.lib" in the "pragma comment(lib,HERE)"? If it is right, please let me know where libeng.lib is. Also, I couldn't find both "libmatlb.lib" and "libmmfile.lib" in the whole matlab folder.
thank you
best regards,
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
You don't need libmatlb.lib or libmmfile.lib anymore for Matlab 7.0, so get rid of those. I don't know how to help you with libeng.lib, though.
Good luck.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
How do you get the values from the pointer? (I'm new at C++.)
I do this:
mxArray *myP; myP = mxCreateDoubleMatrix(1, 1, mxREAL); int inMyP[1][1];
memcpy((void*) mxGetPr(myP), (void*) inMyP, sizeof(inMyP)); matlab.PutVariable("myP", myP); matlab.EvalString("myP=1;"); myP = matlab.GetVariable("myP"); cout << myP << endl;
But myP isn't 1.
Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
You created a double matrix: mxCreateDoubleMatrix(....)
but declared an integer array: int inMyP[1][1];
change this line to double inMyP[1][1];
Best regards, A. Riazi
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Yay! I got it to work. This is the code, slightly modified from above. The way to fix it is to use the memcpy function, but flip the variables.
mxArray *myP = NULL; myP = mxCreateDoubleMatrix(1, 1, mxREAL); double inMyP[1][1]; //matlab.PutVariable("myP", myP); //Don't need. matlab.EvalString("myP = 1"); myP = matlab.GetVariable("myP");
memcpy((void*) inMyP, (void*) mxGetPr(myP), sizeof(inMyP)); //This was the fix, notice that the variables are changed around. cout << inMyP[0][0] << endl; cout << endl; mxDestroyArray(myP);
Thanks a bunch for your help.
-- modified at 16:09 Wednesday 10th January, 2007
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
myP is a pointer to mxArray structure. Then by using
cout << myP << endl; you will see address of pointer. For printing the content of the matrix, use mlfPrintMatrix() function.
Here is the code:
mxArray *A;
A=mxCreateDoubleMatrix(3, 3, mxREAL);
memcpy(mxGetPr(A), (void *) imMyP, 3 * 3 * sizeof(double));
mlfPrintMatrix(A); //printing the matrix content
For more info, please see my other article: Solving Engineering Problems Using MATLAB C API[^]
Best regards, A. Riazi
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I'm currently using MATLAB version 7.3.0.267(R2006b)

-- modified at 14:58 Friday 1st December, 2006
|
| Sign In·View Thread·PermaLink | 4.67/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
In fact, neither "matlab.h" nor "matrix.h" is needed to run this demo in Matlab 7.0! Also, "libmatlb.lib" and "libmmfile.lib" should be removed.
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
|
Dear Riazi, I'm currently building a C++ project and hoping to use the MATLAB ploting function to show the results. I already loaded your code into the project folder but there seems to be a runtime error, for example, "...undefined reference to CMatlabEng::CMatlabEng()..." I think my problem is how to intergrate/compile your code with mine. In other words, I don't know how to put your code into my makefile. Please, Riazi, if you have any suggestion or know of any way to make this work, please help. Thank you very much. Nik.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
As I know, MATLAB Engin API only works under windows. Because the API uses Automation (ActiveX) technology.
Best regards, A. Riazi
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
can you tell me how to embed the matlab figure into winform,like list control? i use microsoft vc#2003 and matlab r2006a. thank you very much.
tom
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Hi, I need call some functions of the Intel Library OpenCV from matlab.I'm doing a project with matlab about image processing. My project director told me that there was a direct form for call this Intel library but now it's not possible.then, I'm thinking do it by a MEX-files and need help!!!
How can I do it?
Thank you very much!!!! Pedro Fernandez.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
There are two ways: 1- Writing your own MEX files. 2- Create an ActiveX control containing the OpenCV codes then using the control inside your m-files.
Best regards, A. Riazi
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Mr. Riazi,
I want to use your program, I add the lib like that? #pragma comment(lib, "C:\MATLAB701\extern\lib\win32\lcc\libeng.lib") #pragma comment(lib, "C:\MATLAB701\extern\lib\win32\lcc\libmx.lib") #pragma comment(lib, "C:\MATLAB701\extern\lib\win32\lcc\libmatlb.lib") #pragma comment(lib, "C:\MATLAB701\extern\lib\win32\lcc\libmat.lib") #pragma comment(lib, "C:\MATLAB701\extern\lib\win32\lcc\libmmfile.lib")
cause my matlab lib are in C:\MATLAB701\extern\lib\win32\lcc.
but I got this error while I compiled the project:
Compiling... MatlabClass.cpp c:\testmatlab\eng_demo\matlabclass.cpp(4) : fatal error C1083: Cannot open precompiled header file: 'Debug/MatlabClass.pch': No such file or directory Error executing cl.exe.
MatlabClass.obj - 1 error(s), 0 warning(s)
Your commnets and help is highly appreciated. Best, Reza
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Salam The error is because of the precompiled header file (*.pch). Try to clean your build and compile the project again.
Best regards, A. Riazi
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|