Matlab C混合编程
[cpp]?view plaincopy
假設(shè)你把hello.c放在了C:\TEST\下,在Matlab里用CD C:\TEST\ 將當(dāng)前目錄改為C:\TEST\(注意,僅將C:\TEST\加入搜索路徑是沒(méi)有用的)。現(xiàn)在敲:
mex hello.c
?? 如果一切順利,編譯應(yīng)該在出現(xiàn)編譯器提示信息后正常退出。如果你已將C:\TEST\加入了搜索路徑,現(xiàn)在鍵入hello,程序會(huì)在屏幕上打出一行:hello,world! 看看C\TEST\目錄下,你會(huì)發(fā)現(xiàn)多了一個(gè)文件:HELLO.DLL。說(shuō)明Mex函數(shù)已經(jīng)完成,編譯成功 ? 接口函數(shù)規(guī)范mexFunction介紹 void?mexFunction(int?nlhs,?mxArray?*plhs[],?int?nrhs,?const?mxArray?*prhs[])
nlhs:輸出參數(shù)數(shù)目?
plhs:指向輸出參數(shù)的指針?
nrhs:輸入?yún)?shù)數(shù)目?
例如,使用
[a,b]=test(c,d,e)
調(diào)用mex函數(shù)test時(shí),傳給test的這三個(gè)參數(shù)分別是?prhs[0]=c?,prhs[1]=d?,prhs[2]=e?
當(dāng)函數(shù)返回時(shí),將會(huì)把你放在plhs[0],plhs[1]里的地址賦給a和b,達(dá)到返回?cái)?shù)據(jù)的目的。??
細(xì)心的你也許已經(jīng)注意到,prhs[i]和plhs[i]都是指向類(lèi)型mxArray類(lèi)型數(shù)據(jù)的指針。?這個(gè)類(lèi)型是在mex.h中定義的,事實(shí)上,在Matlab里大多數(shù)數(shù)據(jù)都是以這種類(lèi)型存在。當(dāng)然還有其他的數(shù)據(jù)類(lèi)型,可以參考Apiguide.pdf里的介紹。 為了讓大家能更直觀地了解參數(shù)傳遞的過(guò)程,我們把hello.c改寫(xiě)一下,使它能根據(jù)輸?入?yún)?shù)的變化給出不同的屏幕輸出:
[html]?view plaincopy
將這個(gè)程序編譯通過(guò)后,執(zhí)行hello(1),屏幕上會(huì)打出:?
??????????hello,world!?
而hello(0)將會(huì)得到:?
???????????大家好!?
現(xiàn)在,程序hello已經(jīng)可以根據(jù)輸入?yún)?shù)來(lái)給出相應(yīng)的屏幕輸出。在這個(gè)程序里,除了用到了屏幕輸出函數(shù)mexPrintf(用法跟c里的printf函數(shù)幾乎完全一樣)外,還用到了一個(gè)函數(shù):mxGetScalar,調(diào)用方式如下:?
i=mxGetScalar(prhs[0]);?
"Scalar"就是標(biāo)量的意思。在Matlab里數(shù)據(jù)都是以數(shù)組的形式存在的,mxGetScalar的作用就是把通過(guò)prhs[0]傳遞進(jìn)來(lái)的mxArray類(lèi)型的指針指向的數(shù)據(jù)(標(biāo)量)賦給C程序里的變量。這個(gè)變量本來(lái)應(yīng)該是double類(lèi)型的,通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換賦給了整形變量i。既然有標(biāo)量,顯然還應(yīng)該有矢量,否則矩陣就沒(méi)法傳了。看下面的程序:?
[cpp]?view plaincopy
這樣,就通過(guò)mxGetPr函數(shù)從指向mxArray類(lèi)型數(shù)據(jù)的prhs[0]獲得了指向double類(lèi)型的指針。
但是,還有個(gè)問(wèn)題,如果輸入的不是單個(gè)的數(shù)據(jù),而是向量或矩陣,那該怎么處理呢??通過(guò)mxGetPr只能得到指向這個(gè)矩陣的指針,如果我們不知道這個(gè)矩陣的確切大小,就?沒(méi)法對(duì)它進(jìn)行計(jì)算。?
為了解決這個(gè)問(wèn)題,Matlab提供了兩個(gè)函數(shù)mxGetM和mxGetN來(lái)獲得傳進(jìn)來(lái)參數(shù)的行數(shù)?和列數(shù)。下面例程的功能很簡(jiǎn)單,就是獲得輸入的矩陣,把它在屏幕上顯示出來(lái):?
[cpp]?view plaincopy
編譯完成后,用下面的命令測(cè)試一下:?
[cpp]?view plaincopy
還有就是若是數(shù)據(jù)不是二維的,可以通過(guò)下面的函數(shù)獲得數(shù)據(jù)的維度個(gè)數(shù)(向量:1,矩陣:2,...)以及維度數(shù)組。
需要注意的是,在Matlab里,矩陣第一行是從1開(kāi)始的,而在C語(yǔ)言中,第一行的序數(shù)為零,Matlab里的矩陣元素b(i,j)在傳遞到C中的一維數(shù)組data后對(duì)應(yīng)于data[j*M+i]?。?輸入數(shù)據(jù)是在函數(shù)調(diào)用之前已經(jīng)在Matlab里申請(qǐng)了內(nèi)存的,由于mex函數(shù)與Matlab共用同一個(gè)地址空間,因而在prhs[]里傳遞指針就可以達(dá)到參數(shù)傳遞的目的。但是,輸出參數(shù)卻需要在mex函數(shù)內(nèi)申請(qǐng)到內(nèi)存空間,才能將指針?lè)旁趐lhs[]中傳遞出去。由于返回指針類(lèi)型必須是mxArray,所以Matlab專(zhuān)門(mén)提供了一個(gè)函數(shù):mxCreateDoubleMatrix來(lái)實(shí)現(xiàn)內(nèi)存的申請(qǐng),函數(shù)原型如下:?
???mxArray?*mxCreateDoubleMatrix(int?m,?int?n,?mxComplexity?ComplexFlag)?
???m:待申請(qǐng)矩陣的行數(shù)?
???n:待申請(qǐng)矩陣的列數(shù)?
為矩陣申請(qǐng)內(nèi)存后,得到的是mxArray類(lèi)型的指針,就可以放在plhs[]里傳遞回去了。但是對(duì)這個(gè)新矩陣的處理,卻要在函數(shù)內(nèi)完成,這時(shí)就需要用到前面介紹的mxGetPr。使用?mxGetPr獲得指向這個(gè)矩陣中數(shù)據(jù)區(qū)的指針(double類(lèi)型)后,就可以對(duì)這個(gè)矩陣進(jìn)行各種操作和運(yùn)算了。下面的程序是在上面的show.c的基礎(chǔ)上稍作改變得到的,功能是將輸出處理后的元素:
[cpp]?view plaincopy
當(dāng)然,Matlab里使用到的并不是只有double類(lèi)型這一種矩陣,還有字符串類(lèi)型、稀疏矩陣、結(jié)構(gòu)類(lèi)型矩陣等等,并提供了相應(yīng)的處理函數(shù)。本文用到編制mex程序中最經(jīng)常遇到的一些函數(shù),其余的詳細(xì)情況清參考Apiref.pdf。? 另外,若是不是輸出元素,申請(qǐng)內(nèi)存之后要記得釋放: mwSize?*subScript;?
subScript?=?(mwSize?*)mxCalloc(?numOfDim,?sizeof(?mwSize?)?);? mxFree(?subScript?);?
通過(guò)前面兩部分的介紹,大家對(duì)參數(shù)的輸入和輸出方法應(yīng)該有了基本的了解。具備了這些知識(shí),就能夠滿足一般的編程需要了。但這些程序還有些小的缺陷,以前面介紹的re由于前面的例程中沒(méi)有對(duì)輸入、輸出參數(shù)的數(shù)目及類(lèi)型進(jìn)行檢查,導(dǎo)致程序的容錯(cuò)性很差,以下程序則容錯(cuò)性較好
[cpp]?view plaincopy
在上面的異常處理中,使用了兩個(gè)新的函數(shù):mexErrMsgTxt和mxIsDouble。MexErrMsgTxt在給出出錯(cuò)提示的同時(shí)退出當(dāng)前程序的運(yùn)行。MxIsDouble則用于判斷mxArray中的數(shù)據(jù)是否double類(lèi)型。當(dāng)然Matlab還提供了許多用于判斷其他數(shù)據(jù)類(lèi)型的函數(shù),這里不加詳述。?
需要說(shuō)明的是,Matlab提供的API中,函數(shù)前綴有mex-和mx-兩種。帶mx-前綴的大多是對(duì)mxArray數(shù)據(jù)進(jìn)行操作的函數(shù),如mxIsDouble,mxCreateDoubleMatrix等等。而帶mx前綴的則大多是與Matlab環(huán)境進(jìn)行交互的函數(shù),如mexPrintf,mxErrMsgTxt等等。了解了這一點(diǎn),對(duì)在Apiref.pdf中查找所需的函數(shù)很有幫助。 另外,需要注意的是,當(dāng)代碼的后綴名為.c的時(shí)候,需要一次性把變量聲明完,且放在代碼的最前面,后綴為.cpp不會(huì)出現(xiàn)這個(gè)問(wèn)題。
常用的Mex函數(shù)一覽表
MX Matrix Library
| mwIndex (C and Fortran) | Type for index values |
| mwPointer (Fortran) | Pointer type for platform |
| mwSignedIndex (C and Fortran) | Signed integer type for size values |
| mwSize (C and Fortran) | Type for size values |
| mxAddField (C and Fortran) | Field to structure array |
| mxArray (C and Fortran) | Type for MATLAB array |
| mxArrayToString (C) | Convert array to string |
| mxAssert (C) | Check assertion value for debugging purposes |
| mxAssertS (C) | Check assertion value without printing assertion text |
| mxCalcSingleSubscript (C and Fortran) | Offset from first element to desired element |
| mxCalloc (C and Fortran) | Allocate dynamic memory for array using MATLAB memory manager |
| mxChar (C) | Type for string array |
| mxClassID (C) | Enumerated value identifying class of array |
| mxClassIDFromClassName (Fortran) | Identifier corresponding to class |
| mxComplexity (C) | Flag specifying whether array has imaginary components |
| mxCopyCharacterToPtr (Fortran) | CHARACTER values from Fortran array to pointer array |
| mxCopyComplex16ToPtr (Fortran) | COMPLEX*16 values from Fortran array to pointer array |
| mxCopyComplex8ToPtr (Fortran) | COMPLEX*8 values from Fortran array to pointer array |
| mxCopyInteger1ToPtr (Fortran) | INTEGER*1 values from Fortran array to pointer array |
| mxCopyInteger2ToPtr (Fortran) | INTEGER*2 values from Fortran array to pointer array |
| mxCopyInteger4ToPtr (Fortran) | INTEGER*4 values from Fortran array to pointer array |
| mxCopyPtrToCharacter (Fortran) | CHARACTER values from pointer array to Fortran array |
| mxCopyPtrToComplex16 (Fortran) | COMPLEX*16 values from pointer array to Fortran array |
| mxCopyPtrToComplex8 (Fortran) | COMPLEX*8 values from pointer array to Fortran array |
| mxCopyPtrToInteger1 (Fortran) | INTEGER*1 values from pointer array to Fortran array |
| mxCopyPtrToInteger2 (Fortran) | INTEGER*2 values from pointer array to Fortran array |
| mxCopyPtrToInteger4 (Fortran) | INTEGER*4 values from pointer array to Fortran array |
| mxCopyPtrToPtrArray (Fortran) | Pointer values from pointer array to Fortran array |
| mxCopyPtrToReal4 (Fortran) | REAL*4 values from pointer array to Fortran array |
| mxCopyPtrToReal8 (Fortran) | REAL*8 values from pointer array to Fortran array |
| mxCopyReal4ToPtr (Fortran) | REAL*4 values from Fortran array to pointer array |
| mxCopyReal8ToPtr (Fortran) | REAL*8 values from Fortran array to pointer array |
| mxCreateCellArray (C and Fortran) | Unpopulated N-D cell array |
| mxCreateCellMatrix (C and Fortran) | Unpopulated 2-D cell array |
| mxCreateCharArray (C and Fortran) | Unpopulated N-D string array |
| mxCreateCharMatrixFromStrings (C and Fortran) | Create populated 2-D string array |
| mxCreateDoubleMatrix (C and Fortran) | 2-D, double-precision, floating-point array initialized to 0 |
| mxCreateDoubleScalar (C and Fortran) | Scalar, double-precision array initialized to specified value |
| mxCreateLogicalArray (C) | N-D logical array initialized to false |
| mxCreateLogicalMatrix (C) | 2-D, logical array initialized to false |
| mxCreateLogicalScalar (C) | Scalar, logical array |
| mxCreateNumericArray (C and Fortran) | Unpopulated N-D numeric array |
| mxCreateNumericMatrix (C and Fortran) | Numeric matrix initialized to 0 |
| mxCreateSparse (C and Fortran) | 2-D unpopulated sparse array |
| mxCreateSparseLogicalMatrix (C) | Unpopulated 2-D, sparse, logical array |
| mxCreateString (C and Fortran) | Create 1-by-N array initialized to specified string |
| mxCreateStructArray (C and Fortran) | Unpopulated N-D structure array |
| mxCreateStructMatrix (C and Fortran) | Unpopulated 2-D structure array |
| mxDestroyArray (C and Fortran) | Free dynamic memory allocated by MXCREATE* functions |
| mxDuplicateArray (C and Fortran) | Make deep copy of array |
| mxFree (C and Fortran) | Free dynamic memory allocated by MXCALLOC, MXMALLOC, or MXREALLOC functions |
| mxGetCell (C and Fortran) | Contents of array cell |
| mxGetChars (C) | Pointer to character array data |
| mxGetClassID (C and Fortran) | Class of array |
| mxGetClassName (C and Fortran) | Class of array as string |
| mxGetData (C and Fortran) | Pointer to real data |
| mxGetDimensions (C and Fortran) | Pointer to dimensions array |
| mxGetElementSize (C and Fortran) | Number of bytes required to store each data element |
| mxGetEps (C and Fortran) | Value of EPS |
| mxGetField (C and Fortran) | Field value, given field name and index, into structure array |
| mxGetFieldByNumber (C and Fortran) | Field value, given field number and index, into structure array |
| mxGetFieldNameByNumber (C and Fortran) | Field name, given field number, in structure array |
| mxGetFieldNumber (C and Fortran) | Field number, given field name, in structure array |
| mxGetImagData (C and Fortran) | Pointer to imaginary data of array |
| mxGetInf (C and Fortran) | Value of infinity |
| mxGetIr (C and Fortran) | Sparse matrix IR array |
| mxGetJc (C and Fortran) | Sparse matrix JC array |
| mxGetLogicals (C) | Pointer to logical array data |
| mxGetM (C and Fortran) | Number of rows in array |
| mxGetN (C and Fortran) | Number of columns in array |
| mxGetNaN (C and Fortran) | Value of NaN (Not-a-Number) |
| mxGetNumberOfDimensions (C and Fortran) | Number of dimensions in array |
| mxGetNumberOfElements (C and Fortran) | Number of elements in array |
| mxGetNumberOfFields (C and Fortran) | Number of fields in structure array |
| mxGetNzmax (C and Fortran) | Number of elements in IR, PR, and PI arrays |
| mxGetPi (C and Fortran) | Imaginary data elements in array of type DOUBLE |
| mxGetPr (C and Fortran) | Real data elements in array of type DOUBLE |
| mxGetProperty (C and Fortran) | Value of public property of MATLAB object |
| mxGetScalar (C and Fortran) | Real component of first data element in array |
| mxGetString (C and Fortran) | String array to C-style string |
| mxIsCell (C and Fortran) | Determine whether input is cell array |
| mxIsChar (C and Fortran) | Determine whether input is string array |
| mxIsClass (C and Fortran) | Determine whether array is member of specified class |
| mxIsComplex (C and Fortran) | Determine whether data is complex |
| mxIsDouble (C and Fortran) | Determine whether mxArray represents data as double-precision, floating-point numbers |
| mxIsEmpty (C and Fortran) | Determine whether array is empty |
| mxIsFinite (C and Fortran) | Determine whether input is finite |
| mxIsFromGlobalWS (C and Fortran) | Determine whether array was copied from MATLAB global workspace |
| mxIsInf (C and Fortran) | Determine whether input is infinite |
| mxIsInt16 (C and Fortran) | Determine whether array represents data as signed 16-bit integers |
| mxIsInt32 (C and Fortran) | Determine whether array represents data as signed 32-bit integers |
| mxIsInt64 (C and Fortran) | Determine whether array represents data as signed 64-bit integers |
| mxIsInt8 (C and Fortran) | Determine whether array represents data as signed 8-bit integers |
| mxIsLogical (C and Fortran) | Determine whether array is of type mxLogical |
| mxIsLogicalScalar (C) | Determine whether scalar array is of type mxLogical |
| mxIsLogicalScalarTrue (C) | Determine whether scalar array of type mxLogical is true |
| mxIsNaN (C and Fortran) | Determine whether input is NaN (Not-a-Number) |
| mxIsNumeric (C and Fortran) | Determine whether array is numeric |
| mxIsSingle (C and Fortran) | Determine whether array represents data as single-precision, floating-point numbers |
| mxIsSparse (C and Fortran) | Determine whether input is sparse array |
| mxIsStruct (C and Fortran) | Determine whether input is structure array |
| mxIsUint16 (C and Fortran) | Determine whether array represents data as unsigned 16-bit integers |
| mxIsUint32 (C and Fortran) | Determine whether array represents data as unsigned 32-bit integers |
| mxIsUint64 (C and Fortran) | Determine whether array represents data as unsigned 64-bit integers |
| mxIsUint8 (C and Fortran) | Determine whether array represents data as unsigned 8-bit integers |
| mxLogical (C) | Type for logical array |
| mxMalloc (C and Fortran) | Allocate dynamic memory using MATLAB memory manager |
| mxRealloc (C and Fortran) | Reallocate dynamic memory using MATLAB memory manager |
| mxRemoveField (C and Fortran) | Remove field from structure array |
| mxSetCell (C and Fortran) | Value of one cell of array |
| mxSetClassName (C) | Convert structure array to MATLAB object array |
| mxSetData (C and Fortran) | Set pointer to data |
| mxSetDimensions (C and Fortran) | Modify number of dimensions and size of each dimension |
| mxSetField (C and Fortran) | Set structure array field, given structure field name and array index |
| mxSetFieldByNumber (C and Fortran) | Set structure array field, given field number and index |
| mxSetImagData (C and Fortran) | Imaginary data pointer for array |
| mxSetIr (C and Fortran) | IR array of sparse array |
| mxSetJc (C and Fortran) | JC array of sparse array |
| mxSetM (C and Fortran) | Number of rows in array |
| mxSetN (C and Fortran) | Set number of columns in array |
| mxSetNzmax (C and Fortran) | Set storage space for nonzero elements |
| mxSetPi (C and Fortran) | Set new imaginary data for array |
| mxSetPr (C and Fortran) | Set new real data for array |
| mxSetProperty (C and Fortran) | Set value of public property of MATLAB object |
MEX Library
| mexAtExit (C and Fortran) | Register function to call when MEX-function cleared or MATLAB software terminates |
| mexCallMATLAB (C and Fortran) | Call MATLAB function, user-defined function, or MEX-file |
| mexCallMATLABWithTrap (C and Fortran) | Call MATLAB function, user-defined function, or MEX-file and capture error information |
| mexErrMsgIdAndTxt (C and Fortran) | Display error message with identifier and return to MATLAB prompt |
| mexErrMsgTxt (C and Fortran) | Display error message and return to MATLAB prompt |
| mexEvalString (C and Fortran) | Execute MATLAB command in caller workspace |
| mexEvalStringWithTrap (C and Fortran) | Execute MATLAB command in caller workspace and capture error information |
| mexFunction (C and Fortran) | Entry point to C/C++ or Fortran MEX-file |
| mexFunctionName (C and Fortran) | Name of current MEX-function |
| mexGet (C) | Value of specified Handle Graphics property |
| mexGetVariable (C and Fortran) | Copy of variable from specified workspace |
| mexGetVariablePtr (C and Fortran) | Read-only pointer to variable from another workspace |
| mexIsGlobal (C and Fortran) | Determine whether variable has global scope |
| mexIsLocked (C and Fortran) | Determine whether MEX-file is locked |
| mexLock (C and Fortran) | Prevent clearing MEX-file from memory |
| mexMakeArrayPersistent (C and Fortran) | Make array persist after MEX-file completes |
| mexMakeMemoryPersistent (C and Fortran) | Make memory allocated by MATLAB software persist after MEX-function completes |
| mexPrintf (C and Fortran) | ANSI C PRINTF-style output routine |
| mexPutVariable (C and Fortran) | Array from MEX-function into specified workspace |
| mexSet (C) | Set value of specified Handle Graphics property |
| mexSetTrapFlag (C and Fortran) | Control response of MEXCALLMATLAB to errors |
| mexUnlock (C and Fortran) | Allow clearing MEX-file from memory |
| mexWarnMsgIdAndTxt (C and Fortran) | Warning message with identifier |
| mexWarnMsgTxt (C and Fortran) | Warning message |
參考:
http://blog.sciencenet.cn/blog-620659-579885.html
http://blog.csdn.net/raodotcong/article/details/6295859
總結(jié)
以上是生活随笔為你收集整理的Matlab C混合编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 程序员编程艺术第二章
- 下一篇: 编程艺术 二进制中1的个数