Matlab與C語言程式的應用程式設計介面(轉)

ba發表於2007-08-15
Matlab與C語言程式的應用程式設計介面(轉)[@more@]MATLAB作為世界頂尖的數學應用軟體,以其強大的工程計算、演算法研究、工程繪圖、應用程式開發、資料分析和動態模擬等功能,在航空航天、機械製造和工程建築等領域發揮著越來越重要的作用。而C語言功能豐富,使用靈活方便,目標程式效率高。既有高階語言的優點,又有低階語言的特點。因此,C語言是目前應用最廣的程式語言。雖然MATLAB是一個完整的、功能齊全的程式設計環境,但在某些情況下,與外部環境的資料和程式的互動是非常必須而且有益的。

眾所周知,MATLAB是用M語言程式設計,不能在M檔案中直接呼叫C語言程式。可以透過MATLAB提供的應用程式設計介面(API)來實現與外部的介面,在 MATLAB環境中實現呼叫C語言或Fortran程式、輸入或輸出資料以及和其他軟體程式間建立客戶/伺服器關係等功能。

MATLAB中呼叫C語言程式,必須透過MEX檔案來實現。

一、 C語言的MEX檔案的結構

C語言的MEX檔案是一種動態連線子程式,可以象呼叫M檔案一樣呼叫它。MEX檔案主要有以下幾方面的應用:

(1)在MATLAB中,M檔案的計算速度特別是迴圈迭代的速度遠比C語言慢,因此可以把要求大量迴圈迭代的部分用C語言編寫為MEX檔案,提高計算速度。

(2)已經開發的C語言程式,則不必將其轉化為M檔案而重複勞動,透過新增入口程式mexFunction,可以由MATLAB呼叫。

(3)直接控制硬體,如A/D採集卡,D/A輸出卡等,以用於資料採集或控制應用。
  C語言的MEX檔案的源程式由兩個非常明顯部分組成:

(1)計算程式,即在MEX檔案中完成計算功能的程式程式碼,計算程式可以是普通的C語言程式,按照C語言規則編寫即可

(2)入口程式,將計算程式與MATLAB連線的入口函式mexFunction。入口程式mexFunction相對要複雜一些,函式中有四個引數nlhs、 plhs、nrhs和prhs。這裡nlhs是輸出資料的個數,plhs是指向mxArray(MATLAB中所有資料都由mxArray定義)的輸出資料的指標,nrhs是輸入資料的個數,prhs是指向mxArray的輸入資料的指標。

顯示瞭如何向MEX檔案輸入資料,透過介面函式呼叫計算程式完成運算過程,最後向MATLAB返回計算結果的過程。

二、 使用MEX檔案

上面所述的MEX檔案的兩個主要部分在使用中可以是獨立的,也可以是組合在一起的。不管是哪一種情況,MEX檔案都必須包含標頭檔案"mex.h",以便正常申明入口程式。入口程式的名字必須是mexFunction而且必須包含這些引數:
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])

在C語言的MEX檔案中,引數nlhs和nrhs包含輸出和輸入變數的數目,藉助於這兩個引數,MEX檔案被呼叫。引數plhs和prhs是包含指向MEX檔案輸出和輸入變數的指標的向量,prhs是長度為nrhs的輸入變數的指標陣列, plhs是長度為nlhs的輸出變數的指標陣列。比如從MATLAB命令視窗來呼叫一個MEX檔案:
x=fun(y,z);

則MATLAB編譯器使用下面的變數來呼叫mexFunction:
nlhs=1
nrhs=2
plhs=(pointer)->/*unassigned*/
prhs=(pointer)->y
(pointer)->z

plhs指向只有一個元素的C語言陣列,並且這個元素為空指標。prhs指向含有兩個元素的C語言陣列,其中第一個元素指向mxArray型變數Y,第二個元素指向mxArray型變數Z。

這裡,plhs指向空的陣列是由於輸出x在子程式執行前尚未產生,入口程式的作用就是建立輸出陣列並分配指標plhs[0]指向該陣列。如果plhs[0]沒有賦值,MATLAB將給出輸出變數沒有賦值的警告資訊。

三、C語言程式MEX檔案例項

MATLAB 5 API提供了一系列程式來處理MATLAB所支援的各種資料型別,每一種資料型別都有對應函式共你使用來處理對應的資料。下面給出一個簡單的C語言程式和與之對應的MEX檔案程式碼,該程式的功能是將標量x加倍。

C語言程式如下:


#include "math.h"
void timestwo(double y[], double x[])
{
y[0]=2.0*x[0];
return;
}

下面是與C語言程式功能相同的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("需要一個輸入引數.");
}
else if(nlhs>1){
mexErrMsgTxt("輸出引數太多.");
}
/*輸入變數必須是非複數型別的標量*/
mrows=mxGetM(prhs[0]);
ncols=mxGetN(prhs[0]);
if(!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows==1 && ncols==1)){
mexErrMsgTxt("輸入變數必須是非複數型別的標量.");
}
/*為返回引數建立矩陣*/
plhs[0]=mxCreateDoubleMatrix(mrows, ncols, mxREAL);
/*分配輸入輸出引數的指標*/
x=mxGetPr(prhs[0]);
y=mxGetPr(plhs[0]);
/*呼叫timestwo子函式*/
timestwo(y, x);
}

C 語言是在編譯的時候檢查函式引數。MATLAB可以在M函式中傳遞任意數量和型別的引數,MEX檔案也是如此,不過在程式中必須可靠地處理輸入輸出引數的數目。如果將上面的MEX檔案命名為timestwo.c,就可以對它進行編譯和連結,在MATLAB命令視窗下輸入:
mex timestwo.c

這是產生MEX檔案timestwo.***所必需的步驟,該檔案的副檔名所執行的系統平臺的型別。Windows系統下,副檔名為dll。此時,就可以象呼叫M函式一樣呼叫timestwo了。

在MATLAB命令視窗中輸入:
x=2;
y=timestwo(x);
就可以得到:
y=4;

四、小 結

MEX 檔案雖然具有較強大的功能,但並不是對所有的應用都恰當。MATLAB是一個高效率的程式設計系統,特別適合於工程計算、系統模擬等應用。它的最大優點就是將人們從繁雜的程式中解放出來。因此,能夠用M檔案完成的程式,應儘量使用MATLAB編寫,除非遇到必須使用MEX檔案的情況。

MATLAB的應用程式設計介面是一個功能強大的系統,除了呼叫C或Fortran程式,還可以實現從MATLAB環境中輸入輸出資料、在MATLAB中和其他程式建立客戶/伺服器關係等功能。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-957655/,如需轉載,請註明出處,否則將追究法律責任。

相關文章