作者kaien,2010/02/16
以前我寫過一篇文章,詳細的介紹過MEX的格式,語法,編譯,調試等。可惜記不清放在哪里了。而最近又用到MEX編程,所以只能重新溫習一番。時間有限,只記下簡要流程和注意事項,以便往后查詢之需。
1. MEX的編寫格式
寫MEX程序其實就是寫一個DLL程序,所以你可以使用C,C++,Fortran等多種編程語言來寫。
編寫MEX程序的編輯器可以使用MATLAB的代碼編輯器,也可使用自己的C++編輯器,如VS2008等。
用 MATLAB的編輯器的好處是,MEX函數會加粗高亮顯示,這給程序編寫帶來便利,可惜無法動態調試。如用VC即可編譯也可調試,比較方便。mex的編譯 結果實際上就是一個帶輸出函數mexFunction 的dll文件,所以會用VC編寫和調試dll,就會用VC編寫和調試MEX程序。
a. MEX文件格式
#include "mex.h"
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ){
}
四個參數分別用來輸出和輸入數據: nlhs 輸出參數個數,plhs 輸出參數指針(nrhs和prhs是輸入參數相關的)。
注意: 我們對輸出和輸入參數的操作都是通過指針的方式進行的。(這點很容易理解,因為我們的計算結果是需要傳遞給MATLAB的,實際上我們傳遞的不是數據,而是指針。MATLAB可以通過這些指針,訪問內存中的數據。)
b. 操作輸入數據
對輸入數據進行操作,需要通過MEX函數mxGetPr 得到數據的指針地址。 mxGetM 和 mxGetN 得到矩陣數據的行和列 (返回整數)。對於實矩陣,我們可以定義 double *M; 來對實矩陣數據操作。如:
double *M;
int m,n;
// 指針指向第一個參數的數據地址
M = mxGetPr(prhs[0]);
m = mxGetM(prhs[0]);
n = mxGetN(prhs[0]);
需要注意的是,MATLAB矩陣數據的存儲順序是"從上到下,從左到右"的,這點和Fortran是一樣的。也就是說對於MATLAB的m x n的矩陣A。 A(1,1) 就是 *M,A(2,1) 就是 *(M+1) ,以此類推,A(i,j) 就是 *(M + m*(j-1) + (i-1)).
注意: MATLAB的指標從1開始,C的指標從0開始。
c. 操作輸出數據
對於輸出數據,我們需要首先分配內存空間,有專門的mex函數可以使用,如:
plhs[0] = mxCreateDoubleMatrix(m,n, mxREAL); //生成m x n 的實矩陣。
同輸入數據一樣,要對輸出數據操作,我們也需要一個指向數據的指針變量,如
double *A;
A = mxGetPr(plhs[0]);
下面介紹一下如何使用VS2008編寫MEX並編譯調試。
2. VC中編寫MEX
打開VS2008, 新建項目, 選擇MFC DLL.
a. 配置項目屬性
打開項目屬性配置頁,C++ -> 附加包含目錄 加入MATLAB安裝目錄下的 \extern\include 路徑。
連接器 -> 附加庫目錄 加入MATLAB的 \extern\lib\win32\microsoft 路徑。
連接器 -> 輸入 -> 附加依賴項 輸入libmx.lib libeng.lib libmat.lib libmex.lib 這四個lib文件。
b. 編輯輸出函數
在項目源文件的. def 中EXPORTS段加入 mexFunction, 如:
EXPORTS ; 此處可以是顯式導出 mexFunction
c. 編寫MEX文件
項目文件中新建一個C++文件 如 mexproc.cpp,里面按前面介紹的格式編寫代碼即可。
d. VC編譯MEX
像編譯其他程序那樣直接編譯即可,成功會生成dll文件。如果編譯鏈接時出錯,根據錯誤提示,檢查一下lib和h的路徑是否正確,有無缺少lib文件,代碼是否有語法錯誤等。
3. VC中調試MEX
要 調試MEX程序就要先編譯,再調用她。所以我們需要在MATLAB中調用這個函數,並在VC的MEX程序相應位置處下斷點即可。調用的函數名就是dll的 主文件名,你可以根據自己的需要改名。我們用mymexfun.dll為例,先在VC的 mexFunction 函數代碼段開始處F9下斷。然后 Ctrl+Alt+P附加MATLAB.exe進程。這樣就可以運行命令調試程序了。我們可以在MATLAB的命令行里輸入命令:
[輸出變量] = mymexfun(輸入變量)
(如果命令找不到,檢查一下matlab當前路徑,和path路徑。)
程序一旦被調用,就會被斷在我們的斷點處。接着你就可以像調試C++程序那樣調試MEX程序了。
在MATLAB中編譯MEX可以輸入: mex 文件名.cpp
MATLAB上編譯MEX時,你可以選擇不同的編譯器如lc, gcc等。也可以在編譯時附加lib和h文件。關於mex的命令詳解請參考MATLAB幫助文檔。