MATLAB与C++的接口问题.docx
- 文档编号:17725797
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:20
- 大小:24.03KB
MATLAB与C++的接口问题.docx
《MATLAB与C++的接口问题.docx》由会员分享,可在线阅读,更多相关《MATLAB与C++的接口问题.docx(20页珍藏版)》请在冰点文库上搜索。
MATLAB与C++的接口问题
发信人:
zjliu(Robusting),信区:
Matlab
标题:
MATLAB与C++的接口问题(zz)
发信站:
哈工大紫丁香(FriNov2212:
34:
292002),转信
摘自北京理工大学BBS
MATLAB是什么东东?
不用我多说了,大批的高手会告诉你它的无数好处。
但是MATL
AB程序存在的一般问题是:
1、运算速度较慢,特别是有fori=1:
?
?
?
forj=1:
?
?
?
......
end
end时,那你就死定了。
2、无法脱离MATLAB环境运行,虽然你可以用MATLAB自带的工具把M文件转成可执行程序,但是执行时,你只能看到一个黑黑的窗口,难道,这就是......Windows?
$%&%^$##%&。
3、GUI功能差。
许多大侠不愿意看到2中所述的DOS-Windows界面,于是使用了MATL
AB带的GUI生成工具。
(不要扔臭鸡蛋!
我知道你用GraphicEditor改了一下界面,发现以前的工作全都白做了——因为被覆盖了,西西)但是MATLAB提供的控件和事件实在有限。
GUI界面做好后放在机器里,向尚未进实验室的师妹(们)炫耀一下,还勉强可以增加一些魅力值。
如果被专家看到了,西西。
只怕效果不太美妙。
因此,如果能够实现MATLAB与VC或者BC或者C++BUILDER等可视化设计语言的交互,提高速度,美化界面,使程序更符合Windows的规范,同时又利用MATLAB的强大功能,对任何人来说都很有意义。
我在课题中涉及到了部分MATLAB与C++的接口知识,在这里总结出来,算是抛砖引玉
吧。
其中错误以及偏颇的地方,尚请各位大侠以及高手多多指教,谢谢!
(一)接口种类
用C++(或者C)语言操作MATLAB,有三种途径:
·MEX文件
在MATLAB中可调用的C或Fortran语言程序称为MEX文件。
MATLAB可以直接把MEX文件视为它的内建函数进行调用。
MEX文件是动态链接的子例程,MATLAB解释器可以自动载入并执行它。
MEX文件主要有以下用途:
对于大量现有的C或者Fortran程序可以无须改写成MATLAB专用的M文件格式而在MATLAB中执行。
对于那些MATLAB运算速度过慢的算法,可以用C或者Fortran语言编写以提高效率。
·MAT文件应用程序
MAT文件是MATLAB专用的用于保存数据至磁盘和向MATLAB导入、从MATLAB导出数据的
数据文件格式。
MAT文件提供了一种简便的机制,它允许你在两个平台之间以灵活的方式
移动数据。
而且,它还提供了一种途径来向其它单机MATLAB应用导入或者导出数据。
为了简化在MATLAB环境之外对MAT文件的使用,MATLAB给出了一个操作例程库,通过
它,我们可以使用C/C++或者Fortran程序读写MAT文件。
·引擎应用程序
MATLAB提供了一系列的例程使得别的程序可以调用MATLAB,从而把MATLAB用作一个计算引擎。
MATLAB引擎程序指的是那些通过管道(在UNIX系统中)或者ActiveX(在Windows系统中)与独立MATLAB进程进行通信的C/C++或者Fortran程序。
MATLAB同样提供了一个函数库来启动或者结束MATLAB进程、与MATLAB交换数据以及发送MATLAB命令。
(二)MEX文件
1、一个MEX的例子
#include"mex.h"
/*
*timestwo.c-examplefoundinAPIguide
*
*Computationalfunctionthattakesascalaranddoublesit.
*
*ThisisaMEX-fileforMATLAB.
*Copyright(c)1984-1998TheMathWorks,Inc.
*/
/*$Revision:
1.5$*/
/*本MEX文件的目的是实现timestwo的功能
voidtimestwo(doubley[],doublex[])是你的C++函数*/
voidtimestwo(doubley[],doublex[])
{
y[0]=2.0*x[0];
}
/*下面这个mexFunction的目的是使MATLAB知道如何调用这个timestwo函数*/
voidmexFunction(intnlhs,mxArray*plhs[],
intnrhs,constmxArray*prhs[])
/*nlhs是MATLAB命令行方式下输出参数的个数;
*plhs[]是MATLAB命令行方式下的输出参数;
nrhs是MATLAB命令行方式下输入参数的个数;
*prhs[]是MATLAB命令行方式下的输入参数;*/
{
double*x,*y;
intmrows,ncols;
/*Checkforpropernumberofarguments.*/
if(nrhs!
=1){
mexErrMsgTxt("Oneinputrequired.");
}elseif(nlhs>1){
mexErrMsgTxt("Toomanyoutputarguments");
}
/*在MATLAB命令行方式下,本MEX文件的调用格式是y=timestwo(x)
输入参数(x)个数=1,输出参数(y)个数=1,所以在程序一
开始就检查nrhs是否=1以及nlhs是否>1(因为MATLAB有一个缺省
输出参数ans,所以nlhs可以=0*/
输出参数ans,所以nlhs可以=0*/
/*Theinputmustbeanoncomplexscalardouble.*/
mrows=mxGetM(prhs[0]);/*获得输入矩阵的行数*/
ncols=mxGetN(prhs[0]);/*获得输入矩阵的列数*/
if(!
mxIsDouble(prhs[0])||mxIsComplex(prhs[0])||
!
(mrows==1&&ncols==1)){
mexErrMsgTxt("Inputmustbeanoncomplexscalardouble.");
}/*判断输入矩阵是否是double类,以及它是否只包括单个元素*/
/*为输出创佳一个矩阵,显然这个矩阵也应该是1x1的*/
plhs[0]=mxCreateDoubleMatrix(mrows,ncols,mxREAL);
/*获得指向输入/输出矩阵数据的指针*/
x=mxGetPr(prhs[0]);
y=mxGetPr(plhs[0]);
/*调用C++函数timestwo(y,x)*/
timestwo(y,x);
}
把上面这个文件用MEX编译后,MATLAB命令行下调用的实例
x=2;
y=timestwo(x)
y=
y=
4
2、MEX文件的编程规则
(1)编制自己的C++算法程序
(2)紧跟着定义mexFunction函数,mexFunction的定义法唯一:
它只能是如下形式:
voidmexFunction(intnlhs,mxArray*plhs[],
intnrhs,constmxArray*prhs[])
其名称和参数类型不许有任何改变,在mexFunciton函数中可以调用你刚定义好的C
++程序。
3、MEX文件的编译
MATLAB提供了专门编译MEX文件的工具:
mex,它可以把你做好的C++源程序编译成
.mex文件供MATLAB在命令行方式下调用。
调用时输入你的C++函数名(上例中为timestw
o)。
具体mex的设置和使用方法可以在MATLAB命令行方式下用helpmex命令获得。
(三)MAT文件
1、概述
.MAT文件是MATLAB专用的数据存储格式,由于MATLAB提供了一套可供MATLAB调用的
API函数集,所以我们完全可以在C++中访问.MAT文件。
这样做的意义是:
你可以把计算
过程留给MATLAB,而用C++对计算结果进行分析或者可视化处理。
2、接口
MATLAB提供的API函数集封装于下面两个标准DLL文件中:
libmat.dll,libmx.dll。
前者用于对MAT文件的操作,后者用于对MAT文件中矩阵的操作。
他们的存放路径为:
ATLAB>\bin。 在 libmat.edf,libmx.dbf。 其导出函数的原型位于同一目录下的 mat.h和matrix.h中 有了这些DLL、DEF、H文件,该怎么用C++调用API函数就不用我多说了吧。 3、MATLAB中常用的矩阵类型 ·(复)双精度矩阵(ComplexDouble-PrecisionMatrices) MATLAB中最常用的数据类型便是(复)双精度、非稀疏矩阵,这些矩阵的元素都是 双精度(double)的,矩阵的尺寸为m×n,其中m是总行数,m是总列数。 矩阵数据实际 存放在两个双精度向量中——一个向量存放的是数据的实部,另一个向量存放的是数据 的虚部。 指向这两个向量的指针一般被写做“pr”(pointertorealdata,指向实数 据的指针)和“pi”(pointertoimaginarydata,指向虚数据的指针)”。 如果一 个矩阵的pi为空的话,说明它是实双精度矩阵。 ·稀疏矩阵(SparseMatrices) MATLAB中稀疏矩阵的存储格式与众不同。 如同双精度矩阵一样,它拥有参数pr和pi ,同时它还具用三个附加的参数: nzmax,ir以及jc。 nzmax是个整型数,其值为向量ir及pr、pi(如果存在的话)可能的最大长度。 它是 稀疏矩阵中不为零的元素的个数。 ir指向一个长度为nzmax的整型数阵列,阵列包含的是pr和pi中对应元素的行号。 jc指向一个长度为N+1的整型数阵列(N为矩阵的列数),其中包含的是列号信息。 对于任意的j,如果0≤j≥N-1,jc[j]是第j列中第一个非零项在ir、pr(以及pi)中的 序号,jc[j+1]-1是第j列最后一个非零项的序号。 因此jc[N]总等于nnz——矩阵中非零 项的总个数。 如果nnz小于nzmax,可以继续向矩阵中添加非零项而无需分配额外的存储 空间 。 4、主要函数举例: ·MATFile*matOpen(constchar*filename,constchar*mode)——打开/创建 ·MATFile*matOpen(constchar*filename,constchar*mode)——打开/创建 一个MAT文件; ·intmatClose(MATFile*pMF)——关闭一个MAT文件; ·mxArray*mxCreateDoubleMatrix(intm,intn,mxComplexityflag) ——创建一个(复)双精度矩阵; ·mxArray*mxCreateSparse(intm,intn,intnzmax,mxComplexityflag) ——创建一个稀疏矩阵; ·mxArray*matGetNextArray(MATFile*pMF)——获得MAT文件里面下一个矩阵; ·constchar*mxGetName(constmxArray*pa)——获得矩阵pa的名称; ·voidmxSetName(mxArray*pa,constchar*s)——为矩阵pa设置一个名称; ·intmxGetM(constmxArray*pa)——获得矩阵pa的总行数; ·intmxGetN(constmxArray*pa)——获得矩阵pa的总列数; ·double*mxGetPr(constmxArray*pa)——获得矩阵pa的pr指针; ·int*mxGetIr(constmxArray*pa)——获得稀疏矩阵pa的ir指针; ·int*mxGetJc(constmxArray*pa)——获得稀疏矩阵pa的jc指针; ·intmatPutArray(MATFile*pMF,constmxArray*pA) ——把矩阵pA存储入MAT文件pMAF; ·voidmxDestroyArray(mxArray*pa)——释放矩阵pa(把它从内存中撤销); 5、两个例子: ·获取一个MAT文件中第一个矩阵的信息 ·获取一个MAT文件中第一个矩阵的信息 typedefstruct{ charszFileName[256]; MATFile*pMatFile; mxArray*pArray; charszArrayName[64]; charszErrMsg[256]; unsignedintnArrayDim[2]; boolbIsSparse; }MATFileStruct; intGetMATFileStruct(MATFileStruct*pMAThdr) { if((pMAThdr->pMatFile=matOpen(pMAThdr->szFileName,"r"))==NULL) {strcpy(pMAThdr->szErrMsg,"Can'topenthismatfile"); return(0); }/*打开一个MAT文件*/ if((pMAThdr->pArray=matGetNextArray(pMAThdr->pMatFile))==NULL) {strcpy(pMAThdr->szErrMsg,"Can'tgetarrays"); matClose(pMAThdr->pMatFile); return(0); }/*获取MAT文件中的第一个矩阵*/ }/*获取MAT文件中的第一个矩阵*/ pMAThdr->nArrayDim[0]=mxGetM(pMAThdr->pArray);/*获取其行数*/ pMAThdr->nArrayDim[1]=mxGetN(pMAThdr->pArray);/*获取其列数*/ strcpy(pMAThdr->szArrayName,mxGetName(pMAThdr->pArray));/*获取其名称*/ pMAThdr->bIsSparse=mxIsSparse(pMAThdr->pArray);/*判断它是否是系数矩阵* / mxDestroyArray(pMAThdr->pArray);/*在内存中撤销这个矩阵*/ matClose(pMAThdr->pMatFile);/*关闭MAT文件*/ return (1); } ·创建稀疏矩阵并赋值 inti,j,k,m,n,nzmax,*ir,*jc; double*pr; unsignedshort*pData; mxArray*pa;file: //初始化。 m=pLCMShdr->TrueHdr.nArrayDim[0];file: //获得原矩阵行数。 n=pLCMShdr->TrueHdr.nArrayDim[1];file: //获得原矩阵列数。 nzmax=0; for(i=0;i {if(pData[i]! =0) nzmax++; nzmax++; }file: //计算数据中非零元个数。 if(nzmax nzmax=n; pa=mxCreateSparse(m,n,nzmax,mxREAL);/*创建一个空的稀疏矩阵pa。 */ mxSetName(pa,pLCMShdr->TrueHdr.szArrayName);/*为稀疏矩阵pa设置名称。 */ pr=mxGetPr(pa);file: //获得pa的pr指针。 ir=mxGetIr(pa);file: //获得pa的ir指针。 jc=mxGetJc(pa);file: //获得pa的jc指针。 k=0; for(j=0;j {jc[j]=k;file: //jc[j]: 截至到第j列非零元的个数。 for(i=0;i{if(pData[i]! =0)file: //如果第j列第i行的元素是个非零元。 {ir[k]=i;file: //记录下第k个非零元的行号。 k++; } } pData+=m;file: //移动pData指针到下一列。 } jc[n]=k;file: //jc[n]等于矩阵中非零元的个数。 matPutArray(pmat,pa);file: //把稀疏矩阵pa存入MAT文件pmat。 mxDestroyArray(pa);file: //从内存中撤销矩阵pa。 (五)引擎应用程序 1、简介 引擎应用程序的实质是把MATLAB做为一个引擎,它允许从你自己的C++程序调用这个 引擎。 在运行时,引擎作为一个进程单独运行,你的C++程序也作为一个进程单独运行,二者可以通过进程间的通信机制进行交互。 2、引擎库 MATLAB引擎库包含了若干个控制MATLAB引擎的函数,如下所示: engOpen启动MATLAB引擎 engClose关闭MATLAB引擎 engGetArray从MATLAB引擎中获取一个MATLAB矩阵 engPutArray向MATLAB引擎发送一个MATLAB矩阵 engEvalString执行于一个MATLAB命令 engOutputBuffer创建一个存储MATLAB文本输出的缓冲区 同时,引擎应用程序还可以使用前面提到的API函数。 3、一个例子 从这个示例中,我们看出引擎应用程序是如何编制的: /*$Revision: 1.3$*/ /* *engdemo.c * *Thisisasimpleprogramthatillustrateshowtocallthe *MATLABenginefunctionsfromaCprogram. * *Copyright(c)1996-1998TheMathWorks,Inc. *Allrightsreserved */ #include #include #include #include"engine.h" #defineBUFSIZE256 intmain() { Engine*ep; mxArray*T=NULL,*result=NULL; charbuffer[BUFSIZE]; doubletime[10]={0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0, 8.0,9.0}; 8.0,9.0}; 6-6 /* *StarttheMATLABenginelocallybyexecutingthestring *"matlab". * *Tostartthesessiononaremotehost,usethenameof *thehostasthestringratherthan\0 * *Formorecomplicatedcases,useanystringwithwhitespace, *andthatstringwillbeexecutedliterallytostartMATLAB. */ if(! (ep=engOpen("\0"))){ fprintf(stderr,"\nCan'tstartMATLABengine\n"); returnEXIT_FAILURE; }/*启动MATLAB引擎*/ /* *PARTI * *Forthefirsthalfofthisdemonstration,wewillsenddata *toMATLAB,analyzethedata,andplottheresult. */ /* /* *Createavariableforourdata. */ T=mxCreateDoubleMatrix(1,10,mxREAL);/*创建一个矩阵*/ mxSetName(T,"T");/*设置矩阵的名字为“T”*/ memcpy((void*)mxGetPr(T),(void*)time,sizeof(time));/*向矩阵“T”赋值 */ /* *把矩阵“T”置入MATLAB引擎 */ engPutArray(ep,T) /* *Evaluateafunctionoftime,distance=(1/2)g.*t.^2 *(gistheaccelerationduetogravity). */ engEvalString(ep,"D=.5.*(–9.8).*T.^2;");/*执行MATLAB 命令: D=.5.*(–9.8).*T.^2;*/ /* *绘制图象. */ engEvalString(ep,"plot(T,D);");/*执行MATLAB命令: 绘图*/ engEvalString(ep,"title('Positionvs.Timeforafalling object');");/*执行MATLAB命令: 给图象加标题*/ engEvalString(ep,"xlabel('Time(seconds)');");/*执行
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MATLAB C+ 接口 问题