1、MATLAB 应用程序接口APIMATLAB中的应用程序接口API 前面章节主要叙述MATLAB自身的各种功能和使用方法。作为优秀软件,MATLAB不仅自身功能强大、环境友善、能十分有效地处理各种科学和工程问题,而且具有极好的开放性。这开放性表现在两方面:一,MATLAB适应各科学、专业研究的需要,提供了各种专业性的工具包;二,MATLAB为实现与外部应用程序的“无缝”结合,提供了专门的应用程序接口API。遵循本书“淡化专业,面向通用”的宗旨,本章将集中阐述MATLAB的应用程序接口。本章分五节,各节内容简述如下。 第12.1节集中介绍:如何编写C MEX源码程序,也就是如何为现有的C程序编写
2、接口程序,使之成为MATLAB函数文件;运用这种技术,读者可以把积累的优秀C程序改造成可在MATLAB中方便调用的指令。 第12.2节用于演示:如何编写产生MAT数据文件的C源码程序。读者通过算例入门,就不难借助MAT文件实现MATLAB与外部应用程序的数据交换。 第12.3节围绕MATLAB引擎技术展开。借助这种技术,前台可以是各种外部应用程序编写的界面,而后台计算则可完全交由MATLAB进行。 第12.4节用三个算例来说明如何应用ActiveX实现MATLAB与外部应用程序的通信。在第一个算例中,MATLAB用作为客户,服务器是Excel。在后两个算例中,服务器是MATLAB,而客户是Po
3、werPoint。由此产生的PPT文件,可以在放映过程中,实时地进行MATLAB调用。 第12.5节的内容是:如何借助DDE技术在MATLAB与其他外部程序间进行通信。该节的一个算例演示:VB制作的界面如何借助DDE建立的对话通道调用服务器MATLAB进行计算和显示结果图形。而另一个算例则演示:MATLAB如何以客户身份与服务器Excel建立DDE“热连接”,使MATLAB图形实时地跟随电子表格数据的改变而变化。 值得指出:MATLAB6.0, 6.1版用于API的(MEX、MAT、及引擎)库函数许多已经被废止。本章内容是根据MATLAB6.5编写的。12.1 C语言MEX文件的编写12.1.
4、1 关于MEX文件的一般性说明12.1.2 MEX文件中的MATLAB数据 A=abcd;1234;ABCD A =abcd1234ABCD 12.1.3 C语言MEX文件源程序的构成【例12.1.3-1】列出具有相同运算功能(实现两个双精度实数标量加法)的C+源码程序和C+ MEX源码程序;对C+ MEX源码程序进行编译链接;在MATLAB中调用生成的DLL文件。通过本例,从感性上认识:(A)一般C源码文件如何改写成具有约定格式的C MEX源码文件;(B)C MEX 源码文件的基本结构;(C)基本的编译链接方法;(D)DLL文件的调用方法。(1)#include void myplus(do
5、uble y,double x,double z) y0=x0+z0; return;(2)exm12013_1.cpp#include mex.h / /-void myplus(double y,double x,double z) y0=x0+z0;/-void mexFunction(int nlhs, mxArray *plhs, int nrhs, const mxArray *prhs) / double *x,*y,*z; / int mrows0,ncols0; / int mrows1,ncols1; / if (nrhs!=2) / mexErrMsgTxt(Two in
6、puts required.); / else if (nlhs1) / mexErrMsgTxt(Too many output arguments); / mrows0=mxGetM(prhs0); / ncols0=mxGetN(prhs0); mrows1=mxGetM(prhs1); ncols1=mxGetN(prhs1); / / if (!mxIsDouble(prhs0)|mxIsComplex(prhs0)|!(mrows0=1 & ncols0=1) / mexErrMsgTxt(Inputs must be all noncomplex scalar double.);
7、 / if (!mxIsDouble(prhs1)|mxIsComplex(prhs1)|!(mrows1=1 & ncols1=1) / mexErrMsgTxt(Inputs must be all noncomplex scalar double.); / if (mrows0!=mrows1|ncols0!=ncols1) / mexErrMsgTxt(Inputs must be same dimension.); / / plhs0=mxCreateDoubleMatrix(mrows0,ncols0,mxREAL); / x=mxGetPr(prhs0); / z=mxGetPr
8、(prhs1); / y=mxGetPr(plhs0); / myplus(y,x,z); (3)cd D:mywork mex exm12013_1.cpp dir exm12013_1.* exm1213_1.cpp exm1213_1.dll (4)a=0.111;b=0.222;c=exm12013_1(a,b) c = 0.3330 12.1.4 C MEX文件的执行流程12.1.5 编写C MEX文件的常用库函数和示例12.1.5.1 常用的MEX库函数(1)#include mex.hvoid mexFunction(int nlhs, mxArray *plhs, int nr
9、hs, const mxArray *prhs) /* 其他C源码*/(2)#include mex.hvoid mexErrMsgTxt(const char *error_msg); void mexWarnMsgTxt(const char *warning_msg); (3)#include mex.hint mexCallMATLAB(int nlhs, mxArray *plhs, int nrhs, mxArray *prhs, const char *command_name);(4)#include mex.hint mexEvalString(const char *com
10、mand);(5)#include mex.hmxArray *mexGetVariable(const char *workspace, const char *var_name); int mexPutVariable(const char *workspace, const char *var_name, mxArray *array_ptr);12.1.5.2 常用的MX函数(1)#include matrix.hmxArray *mxCreateNumericMatrix(int m, int n, mxClassID class, mxComplexity ComplexFlag)
11、;(2)#include matrix.hint mxGetM(const mxArray *array_ptr); int mxGetN(const mxArray *array_ptr); void mxSetM(mxArray *array_ptr, int m); void mxSetN(mxArray *array_ptr, int m); (3)#include matrix.hdouble *mxGetPr(const mxArray *array_ptr);double *mxGetPi(const mxArray *array_ptr);void mxSetPr(mxArra
12、y *array_ptr, double *pr);void mxSetPi(mxArray *array_ptr, double *pr);(4)#include matrix.h#include void *mxCalloc(size_t n, size_t size);12.1.5.3 编程示例【例12.1.5.3-1】创建一个C语言MEX文件,实现对MATLAB两个“单行”字符串的合并。本例演示:(A)如何根据MATLAB约定的规则编写C MEX源码;(B)如何构成该文件的调用指令;(C)如何为MEX文件编写在线帮助文件。(1)#include mex.h /#include stri
13、ng.h /-void stringplus(char *input_buf0,char *input_buf1,char *output_buf) strcat(output_buf,input_buf0); strcat(output_buf,input_buf1);/-void mexFunction(int nlhs,mxArray *plhs, int nrhs,const mxArray *prhs) /char *input_buf0,*input_buf1,*output_buf; int buflen,buflen0,buflen1,status; if (nrhs!=2)
14、/ mexErrMsgTxt(Two inputs inquired.); / else if (nlhs1) / mexErrMsgTxt(Too many output arguments.); / if (mxIsChar(prhs0)!=1|mxIsChar(prhs1)!=1) / mexErrMsgTxt(Inputs must be a string.); if (mxGetM(prhs0)!=1|mxGetM(prhs1)!=1) / mexErrMsgTxt(Inputs must be a row vector.); buflen0=(mxGetM(prhs0)*mxGet
15、N(prhs0)+1; / buflen1=(mxGetM(prhs1)*mxGetN(prhs1)+1; / buflen=buflen0+buflen1-1; input_buf0=(char *)mxCalloc(buflen0,sizeof(char); input_buf1=(char *)mxCalloc(buflen1,sizeof(char); output_buf=(char *)mxCalloc(buflen,sizeof(char); / status=mxGetString(prhs0,input_buf0,buflen0); / if (status!=0) mexW
16、arnMsgTxt(Not enough space,String is truncated.); / status=mxGetString(prhs1,input_buf1,buflen1); / if (status!=0) mexWarnMsgTxt(Not enough space,String is truncated.); stringplus(input_buf0,input_buf1,output_buf); / plhs0=mxCreateString(output_buf); / return;(3)cd d:mywork mex exm120153_1.cpp (4)根据
17、以上分析,就可以写出下列exm120153_1.m文件:% exm120153_1.m Two strings are concatenated into a larger string.% Cstr=exm120153_1(Astr, Bstr) 把字符串Astr和Bstr水平串联% Astr 被串联的“单行”字符串% Bstr 被串联的“单行”字符串% Cstr 由Astr在前,Bstr在后,串联而成的字符串。% 2002年11月编写(5)A=1234;B=abcd;C=exm120153_1(A,B) C =1234abcd 【例12.1.5.3-2】用C语言编写MEX源码文件,在运行中
18、实现对MATLAB函数的调用,画出了曲线。本例演示:(A)如何在MEX文件中调用MATLAB的内建指令;(B)如何在MEX文件中调用用户的自编M文件。(1)#include mex.h #define MAX 1000/-void fill( double *pr, int *pm, int *pn, int max ) int i; *pm = max/2; *pn = 1; for (i=0; i (*pm); i+) pri=i*(4*3.14159/max);/-void mexFunction( int nlhs, mxArray *plhs, int nrhs, const mxA
19、rray *prhs ) int m, n, max=MAX; mxArray *rhs1, *lhs1; rhs0 = mxCreateDoubleMatrix(max, 1, mxREAL); fill(mxGetPr(rhs0), &m, &n, MAX); mxSetM(rhs0, m); mxSetN(rhs0, n); mexCallMATLAB(1, lhs, 1, rhs, mexzzy); mexCallMATLAB(0, NULL, 1, lhs, plot); mxDestroyArray(rhs0); mxDestroyArray(lhs0); return;(2)cd
20、 d:mywork mex exm120153_2.cpp (3)exm120153_2 图12.1-2 12.2 MAT数据文件的应用12.2.1 数据的输入输出方法12.2.2 创建MAT文件的C源码程序的编写【例12.2.2-1】目标:用C+编写一个可创建MAT文件的独立应用程序exm12022_1.exe。通过该例演示:(A)可创建MAT文件的独立应用程序的编写步骤;(B)相应C+源程序的基本格式;(C)相应mx-函数和C指令的配合应用。(D)MAT库函数matClose, matGetArray, matOpen, matPutArray, matPutArrayAsGlobal的使
21、用方法;(1)#include #include mat.h #include #define BUFSIZE 255 /-int create(const char *file) / MATFile *pmat; mxArray *pa1, *pa2, *pa3; double data9 = 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 ; char strBUFSIZE; printf(Creating .nn, file); pmat = matOpen(file, w); if (pmat = NULL) printf(Error creat
22、ing n, file); printf(do you have write permission in this directory?)n); return(1); pa1 = mxCreateDoubleMatrix(3,3,mxREAL); mxSetClassName(pa1, LocalDouble); pa2 = mxCreateDoubleMatrix(3,3,mxREAL); mxSetClassName(pa2, GlobalDouble); memcpy(void *)(mxGetPr(pa2), (void *)data, sizeof(data); pa3 = mxCr
23、eateString(MATLAB: the language of technical computing); mxSetClassName(pa3, LocalString); matPutVariable(pmat,LocalDouble, pa1); matPutVariableAsGlobal(pmat,GlobalDouble, pa2); matPutVariable(pmat, LocalString,pa3); memcpy(void *)(mxGetPr(pa1), (void *)data, sizeof(data); matPutVariable(pmat,LocalD
24、ouble, pa1); mxDestroyArray(pa1); mxDestroyArray(pa2); mxDestroyArray(pa3); if (matClose(pmat) != 0) printf(Error closing n,file); return(1); / pmat = matOpen(file, r); if (pmat = NULL) printf(Error reopening n, file); return(1); pa1 = matGetVariable(pmat, LocalDouble); / if (pa1 = NULL) printf(Erro
25、r reading existing matrix LocalDoublen); return(1); if (mxGetNumberOfDimensions(pa1) != 2) printf(Error saving matrix: result does not have two dimensionsn); return(1); pa2 = matGetVariable(pmat, GlobalDouble); / if (pa2 = NULL) printf(Error reading existing matrix GlobalDoublen); return(1); if (!(mxIsFromGlobalWS(pa2) printf(Error saving global matrix: result is not globaln); return(1); pa3 = matGetVariable(pmat, LocalString); / if (pa3 = NULL) printf(Error reading existing matrix LocalStringn); return(1); mxGetString(pa3, str, 255); if (strcmp(str, MATLAB: the language of technic
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1