一、用C/C++编写matlab函数(mexAdd.cpp)供后面测试用
#include "mex.h" double add(double x, double y) { return x + y; } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *a; double b, c; plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); a = mxGetPr(plhs[0]); b = *(mxGetPr(prhs[0])); c = *(mxGetPr(prhs[1])); *a = add(b, c); }
并在matlab中编译:mex mexAdd.cpp
二、安装csh,否则在不能启动matlab引擎即engOpen(NULL)始终返回0
sudo apt-get install tcsh
或
sudo apt-get install csh
三、创建一个目录qtmatlab在下面放源文件main.cpp
#include <QtGui/QApplication> #include <QDebug> #include <cmath> #include <iostream> #include <engine.h> int main(int argc, char *argv[]) { // Test 1:将C++中的数据送入Matlab执行 // [1] 启动Matlab引擎 Engine *ep = engOpen(NULL); if (!ep) { // 定义Matlab引擎指针,启动引擎;失败则返回NULL qDebug() << "Can't start Matlab engine!"; exit(-1); } engSetVisible(ep, false); // [2] 在C++内存空间构造需要计算或者画图的数据 const int N_SIZE = 10; double x[N_SIZE],y[N_SIZE]; for (int i=0; i<N_SIZE; i++) //计算数组x和y { x[i] = (i+1); y[i] = sin(x[i]); //产生正弦值 } // [3] 在C++内存空间定义Matlab数组 mxArray *xx = mxCreateDoubleMatrix(1,N_SIZE, mxREAL); // 定义mxArray,为行,N_SIZE 列的实数数组 mxArray *yy = mxCreateDoubleMatrix(1,N_SIZE, mxREAL); // [4] 将数据拷贝到数组中 memcpy(mxGetPr(xx), x, N_SIZE*sizeof(double)); // 将数组x复制到mxarray数组xx中 memcpy(mxGetPr(yy), y, N_SIZE*sizeof(double)); // [5] 将C++内存空间的数据传输到Matlab引擎中 engPutVariable(ep, "xx",xx); // 将mxArray数组xx写入到Matlab工作空间,命名为xx engPutVariable(ep, "yy",yy); // [6] 执行Matlab引擎 engEvalString(ep, "plot(xx, yy); "); // 向Matlab引擎发送画图命令 // [7] 销毁C++内存空间的数据 mxDestroyArray(xx); // 销毁mxArray数组xx和yy mxDestroyArray(yy); // Test 2:显示Matlab控制台输出信息 // [1] 将Matlab的输出连接到buffer const int BUFSIZE = 1024; char buffer[BUFSIZE] = {'\0'}; engOutputBuffer(ep, buffer, BUFSIZE); // [2] 显示Matlab里数据的值 engEvalString(ep, "xx"); qDebug() << buffer; engEvalString(ep, "yy"); qDebug() << buffer; // Test 3:从Matlab引擎传回数据 mxArray *_xx = engGetVariable(ep, "xx"); double *_x = mxGetPr(_xx); mxArray *_yy = engGetVariable(ep, "yy"); double *_y = mxGetPr(_yy); for (int i = 0; i < N_SIZE; i++) { qDebug() << "i=" << i << "|" << _x[i] << _y[i]; } // 销毁mxArray数组_xx和_yy mxDestroyArray(_xx); mxDestroyArray(_yy); //Test 4:执行自定义函数(刚才写的那个函数) engEvalString(ep, "cd /home/mymotif/matlab_workplace; c = mexAdd(1,2)"); qDebug() << buffer; engClose(ep); //关闭Matlab引擎 return 0; }
四、编译运行
qmake -project
产生qtmatlab.pro
编辑qtmatlab.pro追加下面两行:
INCLUDEPATH += /opt/local/MATLAB/R2012a/extern/include
LIBS += -L"/opt/local/MATLAB/R2012a/bin/glnxa64" -leng -lmat -lmex -lmx -Wl,-rpath=/opt/local/MATLAB/R2012a/bin/glnxa64
其中的/opt/local/MATLAB/R2012a是MATLAB安装路径、需要根据实际环境修改
修改后的qtmatlab.pro内容如下:
###################################################################### # Automatically generated by qmake (2.01a) ?? 3? 16 19:58:53 2016 ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . INCLUDEPATH += /opt/local/MATLAB/R2012a/extern/include LIBS += -L"/opt/local/MATLAB/R2012a/bin/glnxa64" -leng -lmat -lmex -lmx -Wl,-rpath=/opt/local/MATLAB/R2012a/bin/glnxa64 # Input SOURCES += main.cpp
qmake
make
./qtmatlab
五、testmat.c
//gcc-4.9 testmat.c -o testmat -I/opt/local/MATLAB/R2012a/extern/include -L/opt/local/MATLAB/R2012a/bin/glnxa64 -lm -leng -lmat -lmex -lmx #include<stdio.h> #include<math.h> #include<stdlib.h> #include<engine.h> #include<string.h> int main(int argc,char** argv) { Engine *ep; if (!(ep = engOpen("\0"))) //启动matlab 引擎 { fprintf(stderr, "\nCan't start MATLAB engine\n"); return EXIT_FAILURE; } engSetVisible(ep,false); mxArray *H = NULL, *f = NULL, *A = NULL, *b = NULL, *lb = NULL,*x = NULL; H = mxCreateDoubleMatrix(2, 2, mxREAL); f = mxCreateDoubleMatrix(2, 1, mxREAL); A = mxCreateDoubleMatrix(3, 2, mxREAL); b = mxCreateDoubleMatrix(3, 1, mxREAL); lb = mxCreateDoubleMatrix(2,1, mxREAL); x = mxCreateDoubleMatrix(2,1, mxREAL); double HH[2][2]={1,-1,-1,2}; double ff[2][1]={-2,-6}; double AA[3][2]={1,1,-1,2,2,1}; double bb[3][1]={2,2,3}; double llbb[2][1]={0,0}; double xx[2][1]={0,0}; //把C数组转换为Matlab数组 memcpy((void *)mxGetPr(H), (void *)HH, sizeof(double)*2*2); memcpy((void *)mxGetPr(f), (void *)ff, sizeof(double)*2*1); memcpy((void *)mxGetPr(A), (void *)AA, sizeof(double)*3*2); memcpy((void *)mxGetPr(b), (void *)bb, sizeof(double)*3*1); memcpy((void *)mxGetPr(lb), (void *)llbb,sizeof(double)*2*1); memcpy((void *)mxGetPr(x), (void *)xx,sizeof(double)*2*1); //把数组变量写入Matlab环境中 engPutVariable(ep, "H", H); engPutVariable(ep, "f",f); engPutVariable(ep,"A",A); engPutVariable(ep,"b",b); engPutVariable(ep,"lb",lb); engPutVariable(ep,"x",x); //执行字符串命令 int ret1 = engEvalString(ep,"H = [1 -1; -1 2];"); int ret2 = engEvalString(ep,"f = [-2; -6];"); int ret3 = engEvalString(ep,"A = [1 1; -1 2; 2 1];"); int ret4 = engEvalString(ep,"b = [2; 2; 3];"); int ret5 = engEvalString(ep,"lb = zeros(2,1);"); int ret6 = engEvalString(ep,"[x] = quadprog(H,f,A,b,[],[],lb,[],[]);"); char p[256]={0}; char p1[256]={0}; char* ans = "disp(x(1,1));"; char* ans2 = "disp(x(2,1));"; engOutputBuffer(ep,p,240); engEvalString(ep,ans); printf("p:%s\n",p); engOutputBuffer(ep,p1,240); engEvalString(ep,ans2); printf("p1:%s,\n",p1); mxDestroyArray(H); mxDestroyArray(f); mxDestroyArray(A); mxDestroyArray(b); mxDestroyArray(x); engClose(ep); return 0; }
这里只能用gcc4.x编译,最新的gcc5.3会出错
~$ ./testmat
p:>> 0.6667
p1:>> 1.3333
,