matlab与C++的交互
matlab可用mex命令,运行C++/C的代码。其运用的方式如下:
#include "mex.h" void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs != 3) { mexErrMsgTxt("参数个数不正确!"); } int rowNum = mxGetM(prhs[0]); int colNum = mxGetN(prhs[0]); double* pArr = (double*)mxGetPr(prhs[0]); //得到选择的行列信息 //无论是行向量还是列向量均支持 double* pSelRows = (double*)mxGetPr(prhs[1]); double* pSelCols = (double*)mxGetPr(prhs[2]); int selRowsRowNum = mxGetM(prhs[1]); int selRowsColNum = mxGetN(prhs[1]); if (selRowsRowNum!=1 && selRowsColNum!=1) { mexErrMsgTxt("行参数不正确!"); } int selRowsNum = selRowsRowNum*selRowsColNum; int selColsRowNum = mxGetM(prhs[2]); int selColsColNum = mxGetN(prhs[2]); if (selColsRowNum!=1 && selColsColNum!=1) { mexErrMsgTxt("列参数不正确!"); } int selColsNum = selColsRowNum*selColsColNum; plhs[1] = mxCreateDoubleMatrix(2, 1, mxREAL); double* resizedDims = (double*)mxGetPr(plhs[1]); resizedDims[0] = selRowsNum; resizedDims[1] = selColsNum; plhs[0] = mxCreateDoubleMatrix(selRowsNum, selColsNum, mxREAL); double* pResizedArr =(double*)mxGetPr(plhs[0]); //这里因为MATLAB中数据得按列优先 #define ARR(row,col) pArr[(col)*rowNum+row] #define RARR(row,col) pResizedArr[(col)*selRowsNum+row] for(int ri=0; ri<selRowsNum; ri++) { for(int ci=0; ci<selColsNum; ci++) { RARR(ri,ci)=ARR((int)pSelRows[ri]-1,(int)pSelCols[ci]-1); } } mexPrintf("OK!\n"); }
首先,使用mex–setup命令选择编译器,可以调用的编译器的列表参见链接:http://www.mathworks.com/support/compilers/R2013a/index.html,选择好编译器之后,将当前目录调整到需要编译的文件目录,运行mex[cpp language=”文件”][/cpp],如果有makefile,则运行make。编译成功之后会形成同名后缀为.mexw32的文件。
关于上面的代码
函数voidmexFunction(intnlhs,mxArray*plhs[],intnrhs,constmxArray*prhs[]),实际在mex.h文件中定义过了,参:
void mexFunction( int nlhs, /* number of expected outputs */ mxArray *plhs[], /* array of pointers to output arguments */ int nrhs, /* number of inputs */ const mxArray *prhs[] /* array of pointers to input arguments */ );
这相当于一个接口,数据会通过mxArray数据类型传递,此类型定义在mex.h中没有找到,出现在matrix.h中,如下:typedef struct mxArray_tagmxArray;
但是mxArray_tag的定义文件在路径“C:\ProgramFiles\MATLAB\R2011b\extern\include”中没有找到,但是找到了定义如下:
struct mxArray_tag { void *reserved; int reserved1[2]; void *reserved2; int number_of_dims; unsigned int reserved3; struct { unsigned int scalar_flag : 1; unsigned int flag1 : 1; unsigned int flag2 : 1; unsigned int flag3 : 1; unsigned int flag4 : 1; unsigned int flag5 : 1; unsigned int flag6 : 1; unsigned int flag7 : 1; unsigned int private_data_flag : 1; unsigned int flag8 : 1; unsigned int flag9 : 1; unsigned int flag10 : 1; unsigned int flag11 : 4; unsigned int flag12 : 8; unsigned int flag13 : 8; } flags; unsigned int reserved4[2]; union { struct { void *pdata; void *pimag_data; void *reserved5; int reserved6[3]; } number_array; } data; };
如果需要在VC++中使用这些结构,需要在VS中添加路径,如下:
include增加MATLAB的include路径%MATLAB_PATH%/extern/include
lib增加%MATLAB_PATH%/extern/lib/win32/microsoft/msvc70
在VC中新建一个console项目(也可以是win32,mfc等其他项目),项目的link输入增加libeng.lib和libmx.lib。如果需要使用其他的数据结构,则include其他的文件。
发表评论