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其他的文件。

Tagged with: , ,

发表评论

邮箱地址不会被公开。 必填项已用*标注

*