Matlab与Visual C++混合编程学习笔记.docx
《Matlab与Visual C++混合编程学习笔记.docx》由会员分享,可在线阅读,更多相关《Matlab与Visual C++混合编程学习笔记.docx(12页珍藏版)》请在冰豆网上搜索。
![Matlab与Visual C++混合编程学习笔记.docx](https://file1.bdocx.com/fileroot1/2023-1/2/905ca43e-d4c6-49b9-8474-b076d83d8dc7/905ca43e-d4c6-49b9-8474-b076d83d8dc71.gif)
Matlab与VisualC++混合编程学习笔记
Matlab与VisualC++混合编程学习笔记
要实现VC++与matlab的无缝混编,必须充分掌握matlab的C/C++数学库函数和图形库函数,而要运用这两类库函数则必须先熟悉matlab的接口类与接口函数的结构及使用规则。
1Matlab接口类与接口函数的介绍
接口类mwArray
(1)构造函数
mwArray()
默认构造函数,通过它用户可以创建一个未初始化的mwArray类对象(阵列)。
mwArray(constchar*str)
通过该函数可以构造一个字符串型的阵列,并通过输入的字符串指针指向的字符串进行初始化,例如:
mwArrayA(“MATLABmwArraystring”);
mwArray(int32rows,int32cols,double*real,double*imag=0)
通过该函数可以创建一个指定行数、列数、以及实部和虚部数据的二维复数阵列,例如:
doublereal[]={1,2,3,4,5};
doubleimag[]={6,7,8,9,10};
mwArrayA(1,5,real,imag);
mwArray(constmwArray&mtrx)
mwArray(constmxArray*mtrx)
mwArray(doublestart,doublestep,doublestop)
mwArray(int32start,int32step,int32stop)
mwArray(constmwSubArray&a)
mwArray(double)
mwArray(int)
(2)索引和下标函数
operator()
cell()
field()
(3)转换函数
operatordouble()const
(4)内存管理函数
类mwArray对运算符new和delete进行了重载。
(5)输入输出函数
类mwArray对运算符<<和>>进行了重载。
(6)大小函数
定义:
int32Size()const;
int32Size(int32dim)const;
int32Size(int32*dims,intmaxdims=2)const;
例子:
int32dims[2];
mwArraymat=rand(4,4);
mwArraysz;
mat.Size(dims);
sz=size(mat);
(7)数据提取
GetData()
定义:
MatlabMatrix*GetData()const
例子:
mwArrayA=magic(17);
double*real_data=mxGetPr(A.GetData());
SetData()
定义:
MatlabMatrix*GetData()const
例子:
mwArrayA=rand(4),B=magic(10);
B.SetData(A.GetData());//NEVER,NEVERdothis.
ExtractScalar()和ExtractData()
这两个函数为用户提供了一种更为方便而且更安全的获取mwArray类对象的方法,
定义:
doubleExtractScalar(double&,int32)const;
doubleExtractScalar(int&,int32)const;
voidExtractData(int32*);
voidExtractData(double*);
voidExtractData(double*,double*);
例子:
mwArrayA=magic(11)+(rand(11)*i());
doublerdata,cdata;
rdata=A.ExtractScalar(9);//Realpartonly
rdata=A.ExtractScalar(cdata,17);//Realandcomplexpart
int32*integers=newint32[11*11];
A.ExtractData(integers);//Castdoublestointegers
double*real_data=newdouble[11*11];
double*complex_data=newdouble[11*11];
A.ExtractData(real_data);//Realpartonly
A.ExtractData(real_data,complex_data);//Realandcomplexpart
ToString()
定义:
mwStringToString()const;
例子:
mwArrayA="MATLAB";
mwStrings=A.ToString();
char*c=strdup((char*)s);
了解了mwArray,再举关于它在MatlabC++数学库中的应用,就一目了然了
定义:
mwArraysum(constmwArray&A);
mwArrayinv(constmwArray&X);
mwArrayconv(constmwArray&u,constmwArray&v);
应用:
#include"matlab.hpp"
mwArrayA,B,X,Y,u,v,w;//Inputargument(s)
B=sum(A);
Y=inv(X);
w=conv(u,v);
MatlabC++数学库和图形库有大量丰富的库函数,每个函数在Matlab中有着对应的函数完成同样的功能,但是由于Matlab语言和C++语言存在较大的差别,所以二者在函数调用方式上存在在较大的差异,最为明显的一点就是Matlab允许返回多个值,而C++语言中最多只允许返回一个值,如果希望返回更多的值,只能通过指针来实现。
下面分若干种情况,以范例的形式对C++中调用MatlabC++库函数的规则进行说明。
(1)只有一个输出参数和必须的输入参数
Matlab环境调用规则(MATLABSyntax):
A=sin(B);
MatlabC++数学库中的声明(C++Prototype):
mwArraysin(constmwArray&X);
C++调用MatlabC++库函数规则(C++Syntax):
A=sin(B);//A、B均为mwArray类对象
(2)具有可选的输入参数
MATLABSyntax:
A=tril(X);
A=tril(X,K);
C++Prototype:
mwArraytril(constmwArray&X);
mwArraytril(constmwArray&X,constmwArray&K);
C++Syntax:
A=tril(X);
A=tril(X,K);//A、X、K均为mwArray类对象
(3)具有可选的输出参数
MATLABSyntax:
k=find(X);
[i,j]=find(X);
[i,j,v]=find(X);
C++Prototype:
mwArrayfind(constmwArray&X);
mwArrayfind(mwArray*j,constmwArray&X);
mwArrayfind(mwArray*j,mwArray*v,constmwArray&X);
C++Syntax:
i=find(a);
i=find(j,a);
i=find(j,v,a);//i、j、v、a均为mwArray类对象
(4)具有可选的输入和输出参数
MATLABSyntax:
S=svd(X);
[U,S,V]=svd(X);
[U,S,V]=svd(X,0);
C++Prototype:
mwArraysvd(constmwArray&X);
mwArraysvd(mwArray*S,mwArray*V,constmwArray&X);
mwArraysvd(mwArray*S,mwArray*V,constmwArray&X,constmwArray&Zeros);
C++Syntax:
S=svd(Y);
U=svd(S,V,Y);
U=svd(S,V,Y,0);//U、S、V、Y均为mwArray类对象
此外还有变输入参数和变输出参数的形式,规则基本可以按上面几种形式类推,不再赘述。
1.1.2类mwArrayIndex
1.1.3类mwVarargin和类mwVarargout
PurposeGenerateasequenceofindices
C++PrototypemwIndexcolon();
mwIndexcolon(mwArraystart,mwArrayend);
mwIndexcolon(mwArraystart,mwArraystep,mwArrayend);
ArgumentsstartInitialvalue,stepIncrementvalue,endFinalvalue
C++SyntaxB=A(colon());
B=A(colon(1,10));
B=A(colon(1,2,10));
MATLABcolon=start:
stop
Syntaxcolon=start:
step:
stop
混合编程中开发环境设置是一个关键且有点繁琐的过程,可能比较通俗易懂的讲解方法就是通过一个简单的范例逐步说明吧。
不妨耐心细心的跟着走一遍,慢慢会发现,其实混合编程也挺简单挺好玩的^_^
需说明的是,这里只介绍matlab6.x与VC6.0的混合编程。
原因有三:
1、matlab7.x及以上与VC的混合编程发生的本质的变化,而且目前看来还是很多人不太习惯和喜欢的方式,光是发布的软件使用前就需要先安装一个300M以上的MCRInstaller.exe,汗…
2、其实VC6.0和matlab6.x也都挺稳定挺好用的,呵呵,
3、掌握了下面的方法,做一定修改可以推广到VS2003、VS2005与matlab6.x混合编程,但这不是官方推荐的。
前提:
确保电脑上安装了matlab6.x和VC6.0
第一步:
在matlab中建立Test.m,内容如下:
functionTest()
x=-10*pi:
0.1:
10*pi;
y=x.*sin(x);
plot(x,y);
第二步:
配置matlab编译器(Compiler),即在command窗口输入
>>mbuild–setup
PleasechooseyourcompilerforbuildingstandaloneMATLABapplications:
Wouldyoulikembuildtolocateinstalledcompilers[y]/n?
Selectacompiler:
[1]LccCversion2.4inD:
\MATLAB6P5\sys\lcc
[2]MicrosoftVisualC/C++version6.0inD:
\ProgramFiles\MicrosoftVisualStudio
[0]None
Compiler:
2
Pleaseverifyyourchoices:
Compiler:
MicrosoftVisualC/C++6.0
Location:
D:
\ProgramFiles\MicrosoftVisualStudio
Arethesecorrect?
([y]/n):
......
后面就不详细列了,反正选择好,然后y就会success的。
第三步:
使用matlab的mcc命令编译Test.m程序,即在command窗口输入
>>mcc-p-BsglcppTest.m
执行完成即可发现,在Test.m所在的文件夹(work)中多了几个文件,后面VC将用到的是test.cpp和test.hpp文件。
第四步:
在VC中建立一个简单的MFC对话框工程,在主对话框上添加一个“绘图”,并添加按钮的消息响应函数(OnButton1)。
将test.cpp和test.hpp文件拷贝到当前VC工程目录下,并通过“Project”“AddtoProject”“Files”添加到当前工程中。
[attach]49768[/attach]
(提示:
如果是VC的控制台程序,需要在“Project”“General”中选择UseMFCinasharedDLL)
然后进行VC++环境设置,具体包括以下几个方面:
4.1包涵目录设置(这一步设置好了,以后新建的工程不用再设置了)
选择菜单“工具(Tools)”“选项(Options)”在属性页中选择“目录(Directories)”下拉框中选择“IncludeFiles”,在其最后加入:
D:
\MATLAB6P5\EXTERN\INCLUDE\CPP
D:
\MATLAB6P5\EXTERN\INCLUDE
这里D:
\MATLAB6P5为作者电脑上MATLAB的安装路径,若安装路径不同应做相应调整,如下图所示:
[attach]49769[/attach]
再在下拉框中选择LibraryFiles,在最后加入
D:
\MATLAB6P5\EXTERN\LIB\WIN32\MICROSOFT\MSVC60
D:
\MATLAB6P5\EXTERN\LIB\WIN32
如下图所示:
[attach]49770[/attach]
4.2工程设置(每次新建VC工程进行混编都要设置,当然包含库也可以通过一次性修改stdafx.h头文件做到,但那样对于不混编时,有点不好)
建立一个新的VC工程后,为使其能正确的调用matlab库函数或编译函数,应对工程属性进行以下几项设置。
4.2.1选择菜单“工程(Project)”“设置(Settings)”属性页“连接(Link)”下拉列表中选择“输入(Input)”,在“对象/模块库(Object/librarymodules)”文本框中加入libmmfile.liblibmatlb.liblibmx.liblibmat.liblibmatpm.libsgl.liblibmwsglm.liblibmwservices.lib
下面的“忽略库(IgnoreLibraries)”文本框,填msvcrt.lib。
(实际上有时需要根据不同的工程类型进行填写,有人通过实验总结:
忽略指定库msvcrt.lib是因为某些动态链接库和静态链接库会发生冲突(重复定义)问题,在release模式时,如果选择动态连接库,不能忽略msvcrt.lib。
;在release模式时,选择静态链接库,则必须把msvcrt.lib动态链接忽略掉,否则出错。
)
具体如下图所示:
[attach]49771[/attach]
4.2.2选择C/C++属性页,在下拉列表中选择“预处理器(Preprocessor)”,在“预处理器定义Preprocessordefinitions”中加入MSVC,IBMPC,MSWIND,D__STDC_(有些资料上讲解混编时未添加D__STDC_似乎也可以)如下图所示:
[attach]49772[/attach]
4.2.3再在下拉框中选择“预编译的头文件PrecompliedHeaders”,选中“自动使用补偿页眉Automaticuseofprecompiledheaders”,在其中填入stdafx.h,如下图:
[attach]49773[/attach]
接下来,在按钮“绘图”的响应函数中添加:
test();
在对话框类的OnInitDialog函数中添加如下代码:
libmmfileInitialize();
libmwsglmInitialize();
mlfHGInitialize(NULL,NULL);
在对话框的消息WM_DESTROY的处理函数OnDestroy()中加入如下代码:
mlfHGTerminate();
libmmfileTerminate();
libmwsglmTerminate();
现在,可以编译VC工程运行了,结果如下:
[attach]49774[/attach]
第五步:
程序的发布
由于程序中调用了MATLAB数学函数库或图形库中的函数,所以需要附带MATLAB的这些函数库才能在没有安装MATLAB的机器上运行。
幸好MATLAB已经把这两个库的函数打包了,这样就省得我们一个一个去搜集了。
该文件就是位于matlab安装目录中extern\lib\win32子目录中的mglarchive.exe。
运行该程序即可自动把需要的库函数解压到当前目录中,把编译好的程序放到该目录中拷贝到未装matlab的机器上即可实现脱离matlab。
注意:
Debug模式更换为Release模式时应该对应的修改工程设置
对应
mcc
matlab与VC++混编的两个重要的且强大的命令mbuild和mcc,前者我们相对用得较少,故主要一般先从后者mcc的使用入手,其实在上一节中我们已经领略到了它的威力。
实际上,关于mcc(matlabcompilercommand)乃至混合编程,最好的使用教程就是matlab的help和官方网站提供的user’sguide等文档。
这里不妨截取其中的一部分来说明吧,个人觉得原文应该比中文讲解得更细致,当然这里只提供了一部分主干线索,引入门吧,具体深入修行靠个人了。
mcc
InvokeMATLABCompiler
Syntaxmcc[-options]mfile1[mfile2...mfileN]
[C/C++file1...C/C++fileN]
1.Description
mccistheMATLABcommandthatinvokestheMATLABCompiler.YoucanissuethemcccommandeitherfromtheMATLABcommandprompt(MATLABmode)ortheDOSorUNIXcommandline(stand-alonemode).
2.CommandLineSyntax
YoumayspecifyoneormoreMATLABCompileroptionflagstomcc.Mostoptionflagshaveaone-lettername.Youcanlistoptionsseparatelyonthecommandline,forexample:
mcc-m-gmyfun
Youcangroupoptionsthatdonottakeargumentsbyprecedingthelistofoptionflagswithasingledash(-),forexample:
mcc-mgmyfun
Optionsthattakeargumentscannotbecombinedunlessyouplacetheoptionwithitsargumentslastinthelist.Forexample,theseformatsarevalid:
mcc-m-Afullmyfun%Optionslistedseparately
mcc-mAfullmyfun%Optionscombined,Aoptionlast
Thisformatisnotvalid:
mcc-Amfullmyfun%Optionscombined,Aoptionnotlast
3.UsingMacrostoSimplifyCompilation
TheMATLABCompiler,throughitsexhaustivesetofoptions,givesyouaccesstothetoolsyouneedtodoyourjob.Ifyouwantasimplifiedapproachtocompilation,youcanuseonesimpleoption,i.e.,macro,thatallowsyoutoquicklyaccomplishbasiccompilationtasks.IfyouwanttotakeadvantageofthepoweroftheCompiler,youcandowhateveryoudesiretodobychoosingvariousCompileroptions.
Table7-2,MacroOptions,showstherelationshipbetweenthemacroapproachtoaccomplishastandardcompilationandthemultioptionalternative.
[attach]49775[/attach]
UnderstandingaMacroOption.The-moptiontellstheCompilertoproduceastand-aloneCapplication.The-mmacroisequivalenttotheseriesofoptions-t-Wmain-LC-Tlink:
exe-hlibmmfile.mlib
Table7-3,-mMacro,showstheoptionsthatcomposethe-mmacroandtheinformationthattheyprovidetotheCompiler.
[attach]49776[/attach]
4.MacroOptions
Themacrooptionsprovideasimplifiedwaytoaccomplishbasiccompilationtasks.
-g(Debug).Thisoptioni