matlab都有什么接口,介绍MATLAB与C++的几种接口方式
matlab調用c++,應該用mex把cpp編譯成 .mex文件供MATLAB在命令行方式下調用吧
看下面這片文章
文章: 摘自北京理工大學BBS
MATLAB是什么東東?不用我多說了,大批的高手會告訴你它的無數好處。但是MATLAB程序存在的一般問題是:
1、運算速度較慢,特別是有for i=1:???
for j=1:???
......
end
end時,那你就死定了。
2、無法脫離MATLAB環境運行,雖然你可以用MATLAB自帶的工具把M文件轉成可執行程序,但是執行時,你只能看到一個黑黑的窗口,難道,這就是......Windows? $%&%^$##%&。
3、GUI功能差。許多大俠不愿意看到2中所述的DOS-Windows界面,于是使用了MATLAB帶的GUI生成工具。(不要扔臭雞蛋!我知道你用Graphic Editor改了一下界面,發現以前的工作全都白做了——因為被覆蓋了,西西)但是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或者Frotran語言編寫以提高效率。
·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"
void timestwo(double y[], double x[])
{
y[0] = 2.0*x[0];
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
double *x,*y;
int mrows,ncols;
if(nrhs!=1) {
mexErrMsgTxt("One input required.");
} else if(nlhs>1) {
mexErrMsgTxt("Too many output arguments");
}
輸出參數ans,所以nlhs可以=0 */
mrows = mxGetM(prhs[0]);
ncols = mxGetN(prhs[0]);
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) ||
!(mrows==1 && ncols==1) ) {
mexErrMsgTxt("Input must be a noncomplex scalar double.");
}
plhs[0] = mxCreateDoubleMatrix(mrows,ncols, mxREAL);
x = mxGetPr(prhs[0]);
y = mxGetPr(plhs[0]);
timestwo(y,x);
}
把上面這個文件用MEX編譯后,MATLAB命令行下調用的實例
x = 2;
y = timestwo(x)
y =
y =
4
2、MEX文件的編程規則
(1)編制自己的C++算法程序
(2)緊跟著定義mexFunction函數,mexFunction的定義法唯一:
它只能是如下形式:
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
其名稱和參數類型不許有任何改變,在mexFunciton函數中可以調用你剛定義好的C++程序。
3、MEX文件的編譯
MATLAB提供了專門編譯MEX文件的工具:mex,它可以把你做好的C++源程序編譯成 .mex文件供MATLAB在命令行方式下調用。調用時輸入你的C++函數名(上例中為timestwo)。具體mex的設置和使用方法可以在MATLAB命令行方式下用help mex命令獲得。
(三)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中常用的矩陣類型·(復)雙精度矩陣(Complex Double-Precision Matrices)
MATLAB中最常用的數據類型便是(復)雙精度、非稀疏矩陣,這些矩陣的元素都是雙精度(double)的,矩陣的尺寸為m×n,其中m是總行數,m是總列數。矩陣數據實際存放在兩個雙精度向量中——一個向量存放的是數據的實部,另一個向量存放的是數據的虛部。指向這兩個向量的指針一般被寫做“pr” (pointer to real data,指向實數據的指針)和“pi” (pointer to imaginary data,指向虛數據的指針)”。如果一個矩陣的pi為空的話,說明它是實雙精度矩陣。
·稀疏矩陣(Sparse Matrices)
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(const char *filename, const char * mode)——打開/創建
·MATFile *matOpen(const char *filename, const char * mode)——打開/創建一個MAT文件;
·int matClose(MATFile *pMF)——關閉一個MAT文件;
·mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity flag)
——創建一個(復)雙精度矩陣;
·mxArray *mxCreateSparse(int m, int n, int nzmax, mxComplexity flag)
——創建一個稀疏矩陣;
·mxArray *matGetNextArray(MATFile *pMF)——獲得MAT文件里面下一個矩陣;
·const char *mxGetName(const mxArray *pa)——獲得矩陣pa的名稱;
·void mxSetName(mxArray *pa,const char *s)——為矩陣pa設置一個名稱;
·int mxGetM(const mxArray *pa)——獲得矩陣pa的總行數;
·int mxGetN(const mxArray *pa)——獲得矩陣pa的總列數;
·double *mxGetPr(const mxArray *pa)——獲得矩陣pa的pr指針;
·int *mxGetIr(const mxArray *pa)——獲得稀疏矩陣pa的ir指針;
·int *mxGetJc(const mxArray *pa)——獲得稀疏矩陣pa的jc指針;
·int matPutArray(MATFile * pMF, const mxArray * pA)
——把矩陣pA存儲入MAT文件pMAF;
·void mxDestroyArray(mxArray *pa)——釋放矩陣pa(把它從內存中撤銷);
5、兩個例子:
·獲取一個MAT文件中第一個矩陣的信息
·獲取一個MAT文件中第一個矩陣的信息
typedef struct {
char szFileName[256];
MATFile* pMatFile;
mxArray* pArray;
char szArrayName[64];
char szErrMsg[256];
unsigned int nArrayDim[2];
bool bIsSparse;
} MATFileStruct;
int GetMATFileStruct(MATFileStruct *pMAThdr)
{
if((pMAThdr->pMatFile=matOpen(pMAThdr->szFileName,"r"))==NULL)
{ strcpy(pMAThdr->szErrMsg,"Can't open this mat file");
return(0);
}
if((pMAThdr->pArray=matGetNextArray(pMAThdr->pMatFile))==NULL)
{ strcpy(pMAThdr->szErrMsg,"Can't get arrays");
matClose(pMAThdr->pMatFile);
return(0);
}
}
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);
return(1);
}
·創建稀疏矩陣并賦值
int i,j,k,m,n,nzmax,*ir,*jc;
double *pr;
unsigned short *pData;
mxArray *pa; file://初始化。
m=pLCMShdr->TrueHdr.nArrayDim[0]; file://獲得原矩陣行數。
n=pLCMShdr->TrueHdr.nArrayDim[1]; file://獲得原矩陣列數。
nzmax=0;
for(i=0;i
{ if(pData!=0)
nzmax++;
nzmax++;
} file://計算數據中非零元個數。
if(nzmax
nzmax=n;
pa=mxCreateSparse(m,n,nzmax,mxREAL);
mxSetName(pa,pLCMShdr->TrueHdr.szArrayName);
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!=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、一個例子? ? 從這個示例中,我們看出引擎應用程序是如何編制的:
#include
#include
#include
#include "engine.h"
#define BUFSIZE 256
int main()
{
Engine *ep;
mxArray *T = NULL, *result = NULL;
char buffer[BUFSIZE];
double time[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
if (!(ep = engOpen("\0"))) {
fprintf(stderr, "\nCan't start MATLAB engine\n");
return EXIT_FAILURE;
}
T = mxCreateDoubleMatrix(1, 10, mxREAL);
mxSetName(T, "T");
memcpy((void *)mxGetPr(T), (void *)time, sizeof(time));
engPutArray(ep, T)
engEvalString(ep, "D = .5.*(–9.8).*T.^2;");
engEvalString(ep, "plot(T,D);");
engEvalString(ep, "title('Position vs. Time for a falling
object');");
engEvalString(ep, "xlabel('Time (seconds)');");
engEvalString(ep, "xlabel('Time (seconds)');");
engEvalString(ep, "ylabel('Position (meters)');");
printf("Hit return to continue\n\n");
fgetc(stdin);
printf("Done for Part I.\n");
mxDestroyArray(T);
engEvalString(ep, "close;");
*/
engOutputBuffer(ep, buffer, BUFSIZE);
while (result == NULL) {
char str[BUFSIZE];
printf("Enter a MATLAB command to evaluate. This
command should\n");
printf("create a variable X. This program will then
determine\n");
printf("what kind of variable you created.\n");
printf("For example: X = 1:5\n");
printf(">> ");
fgets(str, BUFSIZE–1, stdin);
engEvalString(ep, str);
engEvalString(ep, str);
printf("%s", buffer+2);
printf("\nRetrieving X...\n");
if ((result = engGetArray(ep,"X")) == NULL)
printf("Oops! You didn't create a variable X.\n\n");
else
printf("X is class %s\t\n", mxGetClassName(result));
}
printf("Done!\n");
mxDestroyArray(result);
engClose(ep);
return EXIT_SUCCESS;
}
4、引擎應用程序的編譯對于象上例中的控制臺程序,可以在MATLAB命令行中直接使用帶-f參數的mex命令編譯。
如果在普通win32 application中使用MATLAB引擎,情況則比較復雜。在Windows中,MATLAB引擎是通過ActiveX被調用的。因此你需要先Create一個OLE Automation Sever和一個OLE Client,然后通過OLE方式調用這個MATLAB引擎。具體做法可參閱相關MATLAB隨機文檔。
5、總結MATLAB引擎的調用與其它引擎(例如數據庫引擎)的調用很類似,其步驟是聯接\啟動引擎,然后向引擎發送命令,獲得引擎處理結果。
結束語上面簡要介紹了MATLAB與C++的幾種接口方式,我們可以根據要求的不同采用相應的方式。
此外,MATLAB還提供了一個數學庫,由此數學庫,我們可以獲得對MATLAB內部命令更多的訪問權和更靈活的訪問方式。具體內容可參考MATLAB的相關隨機文檔。
·參考文獻
1、MATLAB隨機文檔:apiguide.pdf
2、MATLAB隨機文檔:apiref.pdf
3、MATLAB隨機文檔:c_math_ref1.pdf
·致謝
感謝loverboy的鼓勵,他聲稱要把這些帖子放到他的主頁上,才使得我能夠在短時間完成這篇接口問題的文章,西西。
·備注
mex編譯器在VC6下的設置可參閱本板19#文
Bluesky的意見:
VC程序員最好用visual matcom。VB用matrixVB mathtool在主頁上提供免費試用,快去下吧。matlab的功能可在你的VC,VB中實現,而且只需兩個dll即可發行。
要放在當前運行的目錄下
主要是c里面一些參數的設置,如庫的添加,lib路徑的設定等。
還可以看matlab的幫助文件MATLAB/Using MATLAB/External InteRFaces/API/Creating C Language MEX-Files/C MEX-Files,里面有張圖講了調用過程非常清楚。
1
總結
以上是生活随笔為你收集整理的matlab都有什么接口,介绍MATLAB与C++的几种接口方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百度网盘自动备份php,Linux定时备
- 下一篇: python 图像无缝拼接,OpenCV