学习了一下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
1)编写“example2.cpp”,从c++里传递数组值到matlab里面绘制正余弦曲线。代码如下:
/*
* 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
解决方法:(该错误详情:http://www.linuxdiyf.com/linux/26371.html)
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
5)再次运行,成功。
test@test:~/WorkSpace/matlabEngine$ g++ main.cpp -o main -leng -lmx
test@test:~/WorkSpace/matlabEngine$ ./main
Hit any key to exit!
运行结果: