学习了一下c++中调用matlab函数的方法。之前一直用system command的形式,但是长时间读取一个动态的文本中的数据,似乎不太稳定,经常卡死在一个错误上"Invalid file identifier. Use fopen to generate a valid file identifier."。想试试用matlab eigen直接获取matlab函数返回值。步骤总结如下。
系统环境:Ubuntu 12.04, g++ 4.6, matlab 2012a
/* * example2.cpp * * This is a simple program that illustrates how to call the * MATLAB engine functions from a C++ program. * * The program pass array from c++ to matlab, and let matlab plot the lines. * */ #include <iostream> #include <math.h> #include "engine.h" #include<string.h> #define PI 3.1415926 using namespace std; int main() { const int N = 100; Engine *ep; //定义Matlab引擎指针。 if (!(ep=engOpen("\0"))) //测试是否启动Matlab引擎成功。 { cout<< "Can't start MATLAB engine!"<<endl; return EXIT_FAILURE; } double *X = new double [N]; double *Y = new double [N]; double *Z = new double [N]; // Generate uniform numbers between -2*PI and 2*PI. for(int index = 0; index < N; index++) { double step = 4*PI/N; double x = step*index - 2*PI; X[index] = x; cout<<X[index]<<" "; // Define Y as cosine values of x. Y[index] = cos(x); // Define Z as sine values of x. Z[index] = sin(x); } //定义mxArray,为1行,N列的实数数组。 mxArray *xx = mxCreateDoubleMatrix(1, N, mxREAL); mxArray *yy = mxCreateDoubleMatrix(1, N, mxREAL); mxArray *zz = mxCreateDoubleMatrix(1, N, mxREAL); //将c++数组中的值复制到对应的mxArray中 memcpy(mxGetPr(xx), X, N*sizeof(double)); memcpy(mxGetPr(yy), Y, N*sizeof(double)); memcpy(mxGetPr(zz), Z, N*sizeof(double)); //将mxArray数组写入到Matlab工作空间 engPutVariable(ep, "x", xx); engPutVariable(ep, "y1", yy); engPutVariable(ep, "y2", zz); //向Matlab引擎发送画图命令。 engEvalString(ep, "plot(x, y1, '-.ms'); hold on; plot(x, y2, '-go');"); //销毁mxArray数组xx和yy。 mxDestroyArray(xx); mxDestroyArray(yy); //Use cin.get() to make sure that we pause long enough to be able to see the plot. cout<<"Hit any key to exit!"<<endl; cin.get(); //关闭Matlab引擎。 engClose(ep); //释放指针内存 delete X; delete Y; delete Z; return EXIT_SUCCESS; }
2)设置matlab路径
sudo gedit /etc/profile
添加:
MATLAB=/opt/MATLAB/R2012a
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MATLAB/bin/glnxa64
export LIBRARY_PATH=$LIBRARY_PATH:$MATLAB/bin/glnxa64
export CPLUS_INCLUDE_PATH=CPLUS_INCLUDE_PATH:$MATLAB/extern/include
执行一下:
source /etc/profile
说明:缺这步会报错:main.cpp:3:20: fatal error: engine.h: No such file or directory
3)编译。报错。
test@test:~/WorkSpace/matlabEngine$ g++ main.cpp -o main
/tmp/ccEBnHhE.o: In function `main':
example2.cpp:(.text+0x16): undefined reference to `engOpen'
example2.cpp:(.text+0x14a): undefined reference to `mxCreateDoubleMatrix'
example2.cpp:(.text+0x162): undefined reference to `mxCreateDoubleMatrix'
example2.cpp:(.text+0x17a): undefined reference to `mxCreateDoubleMatrix'
example2.cpp:(.text+0x18a): undefined reference to `mxGetPr'
example2.cpp:(.text+0x1aa): undefined reference to `mxGetPr'
example2.cpp:(.text+0x1ca): undefined reference to `mxGetPr'
example2.cpp:(.text+0x1f3): undefined reference to `engPutVariable'
example2.cpp:(.text+0x208): undefined reference to `engPutVariable'
example2.cpp:(.text+0x21d): undefined reference to `engPutVariable'
example2.cpp:(.text+0x22e): undefined reference to `engEvalString'
example2.cpp:(.text+0x23a): undefined reference to `mxDestroyArray'
example2.cpp:(.text+0x246): undefined reference to `mxDestroyArray'
example2.cpp:(.text+0x278): undefined reference to `engClose'
collect2: ld returned 1 exit status
解决方法:(该错误详情可以点这里)
test@test:~/WorkSpace/matlabEngine$ g++ main.cpp -o main -leng -lmx
4)运行。报错。
test@test:~/WorkSpace/matlabEngine$ ./main
Can't start MATLAB engine!
表明matlab引擎没有启动成功(编译成功了,但是启动不了)。在这里找到解决方法,原来是engOpen tries to run matlab through csh.解决方法就是安装一下csh。csh is a command language interpreter incorporating a history mechanism , job control facilities , interactive file name and user name completion, and a C-like syntax. It is used both as an interactive login shell and a shell script command processor. tcsh is an enhanced but completely compatible version of the Berkeley UNIX C shell. In most cases csh/tcsh is installed by default. Ubuntu 12.04上面就没有装。
查看当前都装了什么shell:
test@test:~/WorkSpace/matlabEngine$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
安装一下:
test@test:~/WorkSpace/matlabEngine$ sudo apt-get install build-essential csh
在看,出现了:
test@test:~/WorkSpace/matlabEngine$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/bin/csh
test@test:~/WorkSpace/matlabEngine$ g++ main.cpp -o main -leng -lmx
test@test:~/WorkSpace/matlabEngine$ ./main
Hit any key to exit!
参考:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/238828
http://www.4byte.cn/question/360294/trying-to-access-matlab-from-c-using-header.html
http://walkerqt.blog.51cto.com/1310630/1300119
http://blog.chinaunix.net/uid-26980210-id-3365027.html
http://www.cnblogs.com/killkill/archive/2008/11/09/1330200.html
http://cn.mathworks.com/help/matlab/apiref/engopen.html
http://www.cnblogs.com/tiandsp/archive/2013/02/26/2933578.html
http://cens.ioc.ee/local/man/matlab/techdoc/apiref/engopen.html