最近在看的代码里有一部分是matlab与c++进行混编的,借这个机会学习了一下matlab的混编方法。
众所周知,matlab强大的处理矩阵能力在面临其极慢的执行速度时往往让人十分抓狂,于是就有了matlab与C/C++等混编情况的出现了。
首先声明一下,我的matlab版本是2015b(持续更新),vs是2010(懒得换了)。不过vs的版本对于matlab混编没有影响。
matlab混编常用的命令有三个:mcc、mex、mbuild。
mcc将M文件转换成C/C++文件和相应的MEX包裹文件(需要Matlab编辑器),但在特定条件下可以自动调用mbuild或者mex。
mex将C/C++文件(入口函数为mexfunction())编译成MEX(DLL)文件(需要C/C++编辑器)。
mbuild将C/C++文件(入口函数为main())生成可独立运行的C应用程序(需要C/C++编辑器)。
对于从来没有进行过混编的matlab,要先进行配置matlab混编的环境。
mbuild -setup
mex -setup
配置结束后,我们以插值函数为例看看混编的效果。
matlab的混编有很多情况,个人“将m文件转换为库文件使用”是最简单也是最常见的一种方式。
mcc -W cpplib:my -T link:lib spline.m
-W 指定包装函数类型,cpplib是生成c++库文件;-T指定输出文件的目标阶段 link:lib是把链接文件加到共享库
得到下列文件:
我们使用其中的dlll、h和lib文件。
第二步是在vs中新建一个控制台应用程序。由于matlab是64位的,因此需要把平台的参数由Win32改为x64(在生成–>配置管理器中)
由于我们需要用到matlab提供的库文件和头文件,因此需要在项目中将这些目录添加进来(对这里不清晰的同学可以Google一下库文件和头文件相关内容,目录的添加在项目–>属性–>vc++目录中的包含目录和库目录)。我们用到的头文件和库文件matlab已经提供了,在%\MATLAB\R2015b\extern下,分别是include文件夹和lib文件夹。
还要添加附加依赖项。这个可以在属性的输入中添加,也可以在程序中添加
#pragma comment(lib,"mclmcrrt.lib")
#pragma comment(lib,"myspline.lib")
PS:个人比较支持在项目属性里面添加。
工程的主函数比较简单,只是调用了混编得到的子函数罢了,函数的实现可以在上图所示的cpp文件中查看。
下面给出主函数的实现代码:
#include "my.h" // 增加头文件
#include
#include
#include
using namespace std;
// 附加依赖项没有在属性页添加则需加下面两句
// #pragma comment(lib,"mclmcrrt.lib")
// #pragma comment(lib,"my.lib")
int main()
{
// 初始化lib(必须)
if (!myInitialize())
return -1;
int i, j;
double x[11], y[11];
for(i=0; i<11; i++)
{
x[i] = i;
y[i] = sin(x[i]);
}
double xx[41];
for(i=0; i<41; i++)
xx[i] = i*0.25;
double yy[41];
mwArray mwX(1,11,mxDOUBLE_CLASS);
mwArray mwY(1,11,mxDOUBLE_CLASS);
mwArray mwXX(1,41,mxDOUBLE_CLASS);
mwArray mwYY(1,41,mxDOUBLE_CLASS);
mwX.SetData(&(mxDouble)*x, 11); // SetData的第一个参数是mxDouble*类型,而x是double
mwY.SetData(&(mxDouble)*y, 11);
mwXX.SetData(&(mxDouble)*xx, 41);
mwYY.SetData(&(mxDouble)*yy, 41);
spline(1, mwYY, mwX, mwY, mwXX); // 调用spline
cout<<"yy = "<0;
for(j = 0; j < 41; j++)
{
// Get第一个参数表示用1个下标访问元素,j+1是列号(MATLAB下标从1开始,而C++从0开始,故做+1操作)
yy[j] = mwYY.Get(1,j+1);
cout<4)<11)<if(i%7 == 0) cout<// 换行
}
cout<// 终止调用
myTerminate();
getchar();
return 0;
}
运行程序即可得到自变量0-10,步长0.25的正弦函数插值结果了。
其他还有将m文件转换为对应的C\C++文件或者利用图形库画图等,可以参考使用MATLAB的MCC命令生成C/C++程序 和mcc、mbuild和mex命令详解
如果对本文图片中生成的dll、lib、def、exp等文件心存疑惑,可以参考.dll,.lib,.def 和 .exp文件
mcc较为详细的参数参见matlab生成C++文件mcc命令