112MATLAB编译器和API几乎所有使用过MATLAB的科技人员,无不为该软件的简洁、便捷和功能之强大和可靠所震撼,同时也对MATLAB产生了新的期望:一,希望程序能运行得更快;二,希望获得可摆脱MATLAB环境而独立运行的可执行软件;三,希望从其他“非MATLAB”的外部程序中调用MATLAB。本章前6节介绍MATLAB版编译器(Compiler)。由于1.2版与2.0版差异较大,又由于2.0版缺少1.2版具有的优化功能,因此内容安排上将兼顾地论及两个版本。值得指出的是:除Mathworks外,还有其他一些公司生产的编译器,其中比较著名的是MathTools公司的Mediva;据该公司自称,性能优于Mathworks的,且具有绘图功能。本章第7节论及API应用程序接口,扼要地介绍不同平台间的数据传送和MATLAB引擎技术。节后算例演示了,如何从外部调用MATLAB引擎。12.1编译器2.0概述12.1.1编译器2.0的功能12.1.2编译器2.0的性能改进12.1.3编译器2.0的局限性12.1.4把脚本文件改写为函数文件【例12.1.4-1】有一个绘圆的M脚本文件circle.m如下。希望获得一个MEX绘圆程序。(1)原始的绘圆脚本文件[circle.m]clf;r=2;t=0:pi/100:2*pi;x=r*exp(i*t);plot(x,'r*');axis('square')(2)对这脚本文件直接编译将因错误而失败mcc-xcircle???Error:FilecircleisaScriptM-fileandcannotbecompiledwiththecurrentCompiler.Errorin==H:\MATLAB53\toolbox\compiler\mcc.dll(3)把脚本文件改写成函数文件。[circle_f.m]:functioncircle_f(r)clf;t=0:pi/100:2*pi;x=r*exp(i*t);plot(x,'r*');axis('square')(4)再对circle_f.m进行编译,将顺利通过。mcc-xcircle_f%mcc是编译指令,详见12.4节。2(5)运行生成的MEX文件circle_f.dllcircle_f(0.5)%调用circle_f绘制一半径为0.5的圆whichcircle_f%查询所调用的circle_f的路径全称。d:\mywork\circle_f.dll-0.500.5-0.5-0.4-0.3-0.2-0.100.10.20.30.40.5图12.1.4-1MEX文件circle_f.dll所画的圆12.2编译器的安装和配置12.2.1配置MATLAB编译器的前提准备图12.2.1-1【SelectMATLABComponets】对话窗的选项局部图12.2.2为产生MEX文件进行预配置312.2.2.1对MATLAB编译器应用程序mex的设置图12.2.2.1-1为产生MEX文件所产生的配置屏1图12.2.2.1-2为产生MEX文件所产生的配置屏212.2.2.2配置正确性的验证(1)mex应用程序的验证4cdd:\mywork%把用户目录指定为当前目录mexmy_yprime.c%由my_yprime.c文件生成my_yprime.dll文件my_yprime(1,1:4)%运行my_yprime.dll文件whichmy_yprime%获得my_yprime.dll文件的位置信息ans=2.00008.96854.0000-1.0947d:\mywork\my_yprime.dll(2)在MATLAB命令窗中验证mcc应用程序mcc-xmy_yprime_m%1my_yprime_m(1,1:4)whichmy_yprime_mans=2.00008.96854.0000-1.0947d:\mywork\my_yprime_m.dll(3)在DOS提示符后验证mex、mcc应用程序图12.2.2.2-1在DOS状态下验证编译指令12.2.3为产生独立外部应用程序进行预配置12.2.3.1对MATLAB编译器mbuild应用程序的设置(2.0版)图12.2.3.1-1为产生独立外部应用程序所产生的配置屏15图12.2.3.1-2为产生独立外部应用程序所产生的配置屏212.2.3.2对MATLAB编译器mbuild应用程序的设置(1.2版)12.2.3.3配置正确性的验证(1)mbuild应用程序的验证cdd:\mywork%把用户目录指定为当前目录mbuildmy_ex1.c%在d:\mywork下生成my_ex1.exe文件图12.2.3.2-1在DOS窗口运行验证程序my_ex1.exe所得的结果(2)mcc应用程序的验证mcc-pmy_hello.m%16图12.2.3.2-2在DOS窗口运行验证程序my_hello.exe所得的结果(3)在DOS状态下验证mbuild、mcc工作正确性图12.2.3.2-3在DOS状态验证编译指令12.3MATLAB编译器使用入门12.3.1由M文件创建CMEX文件的入门算例【例12.3.1-1】先编写M文件,然后生成相应的MEX文件。该文件用以判断方阵是否奇异。cdd:\mywork(1)在MATLAB的编辑器中,编写下面的函数文件exm1.m。[exm1.m]functiony=exm1(A)[m,n]=size(A);ifm~=n;error('Aninputmatrixshouldben-by-n.')endr=rank(A);ifr==mdisp('Thismatrixisnonsigular')elsedisp('Thismatrixissigular')end(2)把该函数文件存放于用户目录d:\mywork下。(3)在MATLAB命令窗中,运行以下指令对exm1.m进行编译。7mcc-xexm1%编译m文件。(4)调用MEX文件exm1.dll进行计算A=[1,0,1;2,1,0;4,1,4]exm1(A)%调用exm1来判断矩阵A是否奇异。whichexm1%查询所调用的exm1的路径和全称。A=101210414Thismatrixisnonsigulard:\mywork\exm1.dll12.3.2由M文件创建外部应用程序的入门算例【例12.3.2-1】建立一个脱离MATLAB环境,可独立运行的外部程序。该程序的功能是:对于给定矩阵A,如果存在S使得S-1AS=Λ,则要求出一个S,否则给出信息说明所给的矩阵A不能对角化。(1)编写两个M函数文件:exm2.m和exm2_f.m。(第一个文件是主文件。)[exm2.m]functionexm2A=[4,0,0;0,3,1;0,1,3];S=exm2_f(A)[exm2_f.m]functionS=exm2_f(A)[m,n]=size(A);ifm~=nerror('输入矩阵应是方阵!');end;e=eig(A);%检查输入矩阵的特征值是否各异same=0;fori=1:m-1forj=(i+1):mife(j)==e(i)same=1;endendend%A可以对角化的条件是A具有互异特征值或者A为埃尔米特矩阵。ifany(any((A'-A)))&(same==1)error('矩阵无法对角化!');end[v,d]=eig(A);S=v;(2)把这两个函数文件存放于用户自己的目录d:\mywork,并在MATLAB中运行检验。exm2S=1.00000000.70710.707100.7071-0.70718(3)生成独立的外部可执行程序。在MATLAB指令窗中,运行如下指令mcc-mexm2exm2_f(4)打开DOS窗口,在d:\mywork目录下,运行exm2.exe,得如图12.3.2-1的结果。图12.3.2-1在DOS窗口运行生成程序exm2.exe所得的结果12.4编译指令mcc简介12.4.1mcc的基本调用格式12.4.2mcc的选项标志12.4.2.1编译器2.0选项简介12.4.2.2在命令行中指定选项标志【例12.4.2.2-1】假设当前目录上存在一个文件exm3.m,现要求利用M编译器将它转换为C++语言的源码文件,并要求将原M文件中那注释区的内容作为所得C++源码文件的注释。mcc-t-LCpp-Aannotation:commentsexm3%得到exm3.cpp和exm3.hpp12.4.2.3设置缺省选项【例12.4.2.3-1】假设已在d:\mywork下创建了文本文件mccstartup(请注意:该文件不可带扩展名),该文件的内容包括若干编译指令的选项。现要求利用该文件,从exm3.m出发得到C++语言的源文件。cdd:\mywork%将d:\mywork设为当前工作目录typemccstartup%打印文本文件mccstartup的内容-t-LC-Aannotation:none!copymccstartuph:\y9857\temp%将mccstartup转移到临时目录下!copyexm3.mh:\y9857\temp%将待编译M源码转移到临时目录下!delmccstartup,%删除mccstartup!delexm3*%删除原有的编译后文件dirmccstartup%当前目录下是否含有mccstartupdirh:\matlab53\bin\mccstartup%matlab\bin下是否含该文件direxm3*%当前目录下是否含有exm3*1file(s)copied1file(s)copiedmccstartupnotfound.9h:\matlab53\bin\mccstartupnotfound.exm3*notfound.!copyh:\y9857\temp\exm3.md:\myworkmcc-LCppexm3%11file(s)copied???Error:Theoptionsspecifiedwillnotgenerateanyoutputfiles.Pleaseuseoneofthefollowingoptionstogenerateanexecutableoutputfile:-x(generatesaMEX-fileexecutableusingC)-m(generatesastand-aloneexecutableusingC)-p(generatesastand-aloneexecutableusingC++)-S(generatesaSimulinkMEXS-functionusingC)Ortypemcc-?formoreusageinformation.Errorin==H:\MATLAB53\toolbox\compiler\mcc.dll!copyh:\y9857\temp\mccstartupd:\mywork%将mccstartup拷贝到当前目录mcc-LCppexm3%2direxm3*%3!delmccstartup1file(s)copiedexm3.cppexm3.hppexm3.m12.4.2.4编译器1.2选项简介【例12.4.2.4-1】要求利用1.2版编辑器对文件exm4.m进行操作,目标是获得CMEX文件和C语言的独立可执行文件。(1)在5.3版MATLAB指令窗中的执行指令mcc-V1.2exm4mcc-V1.2-emexm4(2)为完成同样任务在5.2版指令窗中的执行指令mccexm4mcc-emexm412.5编译文件的性能优化12.5.1优化原M文件的性能12.5.1.1提高向量化程度【例12.5.1.1-1】本例演示:M文件与MEX文件、向量运算与循环运算的速度比较。(1)编写如下两类函数M文件。functiony=sa(x)x=x+(x==0)*eps;y=sin(x)./x;functiony=saf(x)n=length(x);fork=1:nx(k)=