您的位置:首页 > 编程语言 > MATLAB

C/C++调用matlab

2015-08-02 23:01 417 查看
环境:WIN7 VS2008 MATLAB2009a 版本无所谓 操作上大同小异

首先配置matlab,在命令窗口输入mex -setup (matlab从2012还是2014版本以上就不需要这步了)

然后选择n,如图



因为我装的是VS2008 所以这里我选择5,如图



如果给出的目录是你的VS的安装目录 直接选y 否则选n然后输入的你的VS目录

然后y确认,如图



接着输入 mbuild -setup

操作和mex -setup相同

matlab 到此配置完毕

接着我们配置VS,以VS2008为例,其他版本操作大致相同

新建项目然后菜单栏里工具-选项-项目和解决方案-VC++目录,注意平台选项卡,MATLAB的位数要和VS对应,就是说,如果你的MATLAB是64位的,那么你的VS工程也要是64位的,因为我的MATLAB是64位的,所以在VS中把平台切换成X64,然后在“显示以下内容的目录”选项卡中选择 包含文件,然后将matlab目录下extern/include写进去,如图(注意VS高版本,如VS2013,VC++目录是包含在 右键-属性选项卡中,不需要到工具目录中找)



然后还是那个选项卡,选择库文件,将C:\Program Files\MATLAB\R2009a\extern\lib\win64\microsoft包含进去(注意我是64位MATLAB+64位VS工程),如图



然后确定

然后菜单栏-项目-属性-配置属性-链接器-输入-附加依赖项,将

libeng.lib

libmx.lib

libmat.lib

写进去,每写一个换一次行,确定

VS配置完毕

然后有两种调用MATLAB的方法,一种是将MATLAB的函数封装成DLL给C/C++调用,一种是在C中直接调用MATLAB引擎执行命令

这里先介绍第一种

首先在MATLAB中写个函数文件.m这里我就写个生成高斯白噪声的了

function result = getWgn(height, width)
result = wgn(height, width, 1);

保存为getWgn.m

接着在MATLAB命令窗口用以下格式 mcc -B csharedlib:funcName funcName.m

这里就是mcc -B cshardlib:getWgn getWgn.m

等会儿.m文件目录就会生成一堆文件,从里面找到.lib .h .dll这3个文件,复制到VS工程所在目录



接着再在属性-附加依赖项里面写入getWgn.lib 和 mclmerrt.lib

编写程序的时候头文件要包含getWgn.h

C++中调用代码如下

//调用matlab得到heigth * width的高斯白噪声
void GetWgn(double &wgn, int height, int width)
{
// 将大小转换为doulbe
double dHeight = height, dWidth = width;

//初始化
getWgnInitialize();

//定义matlab可接受的double矩阵
mxArray *mxHeight = mxCreateDoubleMatrix(1, 1, mxREAL);
mxArray *mxWidth = mxCreateDoubleMatrix(1, 1,mxREAL);
mxArray *result = mxCreateDoubleMatrix(height, width, mxREAL);

//给矩阵赋值
memcpy((void *)mxGetPr(mxHeight), (void *)&dHeight, sizeof(double));
memcpy((void *)mxGetPr(mxWidth), (void *)&dWidth, sizeof(double));

//执行matlab函数
mlfGetWgn(1, &result, mxHeight, mxWidth);

//matlab中以列序排列,C/C++中以行序存储,所以要执行转换
double *p = (double *)mxGetPr(result);
for(int i = 0 ;i < height; ++i)
for(int j = 0 ; j < width; ++j)
wgn[i][j] = p[j * height + i];

//结束调用
getWgnTerminate();
}

写的时候参考getWgn.h头文件里的函数

大致格式如下

首先要调用funcNameInitialize()进行初始化 这里是getWgnInitialize()

结束的时候要调用funcNameTerminate()结束

执行写的.m函数用mlffuncName(arg1, arg2, arg3)调用

打开头文件我们可以看到



第一个nargout意思是输出参数个数 在.m文件中 我只写了一个输出参数result,所以这里nargout=1

然后传给mlfGetWgn剩下的3个参数中 第一个mxArray **result代表输出结果 后面2个是输入参数

MATLAB中是以矩阵为基本单位的,所以调用的时候我们也要以矩阵为参数调用

具体的使用mxArray *T来定义一个指向矩阵的指针,然后用mxCreateDoubleMatrix来创建double矩阵

mxCreateDoubleMatrix包含3个参数,前两个是矩阵大小,最后一个是矩阵类型,mxREAL代表实数,还有一个是复数的类型

这里我用

mxArray *mxHeight = mxCreateDoubleMatrix(1, 1, mxREAL);

 mxArray *mxWidth = mxCreateDoubleMatrix(1, 1,mxREAL);

创建了2个1*1的double矩阵用来当做参数height, width传递

返回的是height * width的矩阵,所以定义的result是

mxArray *result = mxCreateDoubleMatrix(height, width, mxREAL);

给矩阵赋值用memcpy函数,mxGetPr函数是取得矩阵的指针,使其可以在C中被操作

赋值完毕后就可以执行函数了,这里result就是得到的结果

这里有一点要注意的,MATLAB中,数组是以列序存储的,而C是以行序存储的

什么意思呢,举个例子

如果在MATLAB中用a = [1 2 ; 3 4];

得到的矩阵为

1 2

3 4

在内存中存储是1 3 2 4的顺序

如果在C中创建一个数组a[2][2] = {1, 2, 3, 4};

得到的数组为

1 2

3 4

在内存中存储是1 2 3 4的顺序

所以从MATLAB中得到结果一般要进行行序列序的转换

这里首先我们用double *p = (double *)mxGetPr(result);

取得数据的指针进行操作

然后

for(int i = 0 ;i < height; ++i)

  for(int j = 0 ; j < width; ++j)

   wgn[i][j] = p[j * height + i];

进行行序列序的转换 这样wgn就是得到的结果了

暂时我用的最多的是这种方式

后面那种调用MATLAB引擎的方法以后再写
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: