MATLAB与C++的接口问题.docx

上传人:b****6 文档编号:8115429 上传时间:2023-01-28 格式:DOCX 页数:15 大小:23.93KB
下载 相关 举报
MATLAB与C++的接口问题.docx_第1页
第1页 / 共15页
MATLAB与C++的接口问题.docx_第2页
第2页 / 共15页
MATLAB与C++的接口问题.docx_第3页
第3页 / 共15页
MATLAB与C++的接口问题.docx_第4页
第4页 / 共15页
MATLAB与C++的接口问题.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

MATLAB与C++的接口问题.docx

《MATLAB与C++的接口问题.docx》由会员分享,可在线阅读,更多相关《MATLAB与C++的接口问题.docx(15页珍藏版)》请在冰豆网上搜索。

MATLAB与C++的接口问题.docx

MATLAB与C++的接口问题

发信人:

zjliu(Robusting),信区:

Matlab

标题:

MATLAB与C++的接口问题(zz)

发信站:

哈工大紫丁香(FriNov2212:

34:

292002),转信

摘自北京理工大学BBS

MATLAB是什么东东?

不用我多说了,大批的高手会告诉你它的无数好处。

但是MATLAB程序存在的一般问题是:

1、运算速度较慢,特别是有fori=1:

?

?

?

forj=1:

?

?

?

......

end

end时,那你就死定了。

2、无法脱离MATLAB环境运行,虽然你可以用MATLAB自带的工具把M文件转成可执行程序,但是执行时,你只能看到一个黑黑的窗口,难道,这就是......Windows?

$%&%^$##%&。

3、GUI功能差。

许多大侠不愿意看到2中所述的DOS-Windows界面,于是使用了MATLAB带的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++函数名(上例中为timestwo)。

具体mex的设置和使用方法可以在MATLAB命令行方式下用helpmex命令获得。

(三)MAT文件

1、概述

.MAT文件是MATLAB专用的数据存储格式,由于MATLAB提供了一套可供MATLAB调用的API函数集,所以我们完全可以在C++中访问.MAT文件。

这样做的意义是:

你可以把计算过程留给MATLAB,而用C++对计算结果进行分析或者可视化处理。

2、接口

MATLAB提供的API函数集封装于下面两个标准DLL文件中:

libmat.dll,libmx.dll。

前者用于对MAT文件的操作,后者用于对MAT文件中矩阵的操作。

他们的存放路径为:

\bin。

\extern\include中有与前面两个DLL对应的DEF文件:

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)');");/*执行MATLAB命令:

设置X轴

坐标*/

engEvalString(ep,"xlabel('Time(seconds)');");/*执

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1