3-4 @茬簡瑼?MEX 仵

以下介紹一個簡單的 C 程式碼,它可將一個輸入純量(資料型態為 double)乘以 2,此程式碼已內建在 MATLAB 光碟中,其位置為:

{MATLAB root}\extern\examples\refbook\timestwo.c

作者已在原程式碼加上詳細的中文註解,並改名為 scalarx2.c,更改後的 C 程式碼內容列出如下:

原始檔(03-應用程式介面/scalarx2.c):(灰色區域按兩下即可拷貝)
/* 此函式為 MATLAB 的 MEX 檔案,其輸入為一個純量,輸出則為此純量的兩倍。 */

#include "mex.h"	/* mex.h 包含 mxArray 結構的定義,以及其他相關資訊 */

/* prhs = pointer to the right-hand-side arguments,即指向輸入變數列的指標 */
/* prls = pointer to the  left-hand-side arguments,即指向輸出變數列的指標 */
#define IN  prhs[0]	/* 定義 IN  為此函式的第一個輸入變數,以便後續取用 */
#define OUT plhs[0]	/* 定義 OUT 為此函式的第一個輸出變數,以便後續取用 */

/* 此函式的功能為將 x 的第零個元素乘以2,在將結果送到 y 的第零個元素。 */
/* 此函式將會被 mexFunction 所呼叫。 */
void timestwo(double y[], double x[]) {
	y[0] = 2.0*x[0];
}

/* 此函式為和 MATLAB 溝通的主要函式 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] ) {
	double *x, *y;
	int    no_rows, no_cols;
  
	/* 檢查輸出和輸入變數個數是否都是1,其中		  */
	/* nrhs = no. of right-hand-side arguments(輸入變數個數)*/
	/* nlhs = no. of  left-hand-side arguments(輸出變數個數)*/
	if(nrhs!=1)	/* 檢查輸入變數個數是否是1 */
		mexErrMsgTxt("One input required.");
	if(nlhs>1)	/* 檢查輸出變數個數是否是1 */
		mexErrMsgTxt("Too many output arguments");
  
	/* 檢查輸入變數是否合格 */
	no_rows = mxGetM(IN);	/* 橫列維度 */
	no_cols = mxGetN(IN);	/* 直行維度 */
	if(!(no_rows==1 && no_cols==1))	/* 檢查輸入變數是否為純量 */
		mexErrMsgTxt("Input must be a scalar.");
	if(mxIsComplex(IN))		/* 檢查輸入變數是否為實數 */
		mexErrMsgTxt("Input must be noncomplex.");
	if(!mxIsDouble(IN))		/* 檢查輸入變數是否為 double */
		mexErrMsgTxt("Input must be a double.");
  
	/* 配置記憶體給輸出變數 */
	OUT = mxCreateDoubleMatrix(no_rows, no_cols, mxREAL);
  
	/* 取得輸入和輸出變數的指標 */
	x = mxGetPr(IN);
	y = mxGetPr(OUT);
  
	/* 執行實際的運算:將輸入純量乘以2 */
	timestwo(y, x);
}

上面 scalarx2.c 程式碼均己附上豐富註解,故在此不再說明。接著在 MATLAB 中,呼叫 C 編譯器對 scalarx2.c 程式碼進行編譯如下:

>> mex scalarx2.c 編譯完後,確認可執行檔是否存在,可輸入如下: >> which scalarx2 D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\scalarx2.mexw64

接著即可進行各項測試,可輸入如下:

>> scalarx2(8.5) ans = 17 >> scalarx2('String input') ??? Input must be a scalar. >> scalarx2([1 2 3]) ??? Input must be a scalar. 若同時有 scalarx2.m 及 scalarx2.mexw64 存在於同一目錄下,MATLAB 會選用 scalarx2.mexw64 檔來執行,而忽略 scalarx2.m。但是如果輸入「help scalarx2」,MATLAB 會列出 scalarx2.m 的線上輔助說明(因為無法在 scalarx2.c 及 scalarx2.mexw64 擺置相關的線上輔助說明)。換句話說,有關 scalarx2.mexw64 的線上輔助說明,就必須置於 scalarx2.m 之內。例如我們可以顯示 scalarx2.m 的內容: >> type scalarx2.m function out = scalarx2(in) % SCALARX2 A scalar version of "times two". % This serves as an example of putting on-line help in an % M-file, but the actual program body is in another MEX-file % with the same major file name. 或顯示 scalarx2.m 的說明: >> help scalarx2 SCALARX2 A scalar version of "times two". This serves as an example of putting on-line help in an M-file, but the actual program body is in another MEX-file with the same major file name. 但若要進行執行時,我們可以使用 which 指令來顯示 scalarx2 所對應的執行檔案是 MEX 檔案而不是 M 檔案: >> which scalarx2 D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\scalarx2.mexw64
MATLAB程式設計:進階篇