Matlab C混合编程
[cpp] view plaincopy
假设你把hello.c放在了C:\TEST\下,在Matlab里用CD C:\TEST\ 将当前目录改为C:\TEST\(注意,仅将C:\TEST\加入搜索路径是没有用的)。现在敲:
mex hello.c
如果一切顺利,编译应该在出现编译器提示信息后正常退出。如果你已将C:\TEST\加入了搜索路径,现在键入hello,程序会在屏幕上打出一行:hello,world! 看看C\TEST\目录下,你会发现多了一个文件:HELLO.DLL。说明Mex函数已经完成,编译成功 接口函数规范mexFunction介绍 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
nlhs:输出参数数目
plhs:指向输出参数的指针
nrhs:输入参数数目
例如,使用
[a,b]=test(c,d,e)
调用mex函数test时,传给test的这三个参数分别是 prhs[0]=c ,prhs[1]=d ,prhs[2]=e
当函数返回时,将会把你放在plhs[0],plhs[1]里的地址赋给a和b,达到返回数据的目的。
细心的你也许已经注意到,prhs[i]和plhs[i]都是指向类型mxArray类型数据的指针。 这个类型是在mex.h中定义的,事实上,在Matlab里大多数数据都是以这种类型存在。当然还有其他的数据类型,可以参考Apiguide.pdf里的介绍。 为了让大家能更直观地了解参数传递的过程,我们把hello.c改写一下,使它能根据输 入参数的变化给出不同的屏幕输出:
[html] view plaincopy
将这个程序编译通过后,执行hello(1),屏幕上会打出:
hello,world!
而hello(0)将会得到:
大家好!
现在,程序hello已经可以根据输入参数来给出相应的屏幕输出。在这个程序里,除了用到了屏幕输出函数mexPrintf(用法跟c里的printf函数几乎完全一样)外,还用到了一个函数:mxGetScalar,调用方式如下:
i=mxGetScalar(prhs[0]);
"Scalar"就是标量的意思。在Matlab里数据都是以数组的形式存在的,mxGetScalar的作用就是把通过prhs[0]传递进来的mxArray类型的指针指向的数据(标量)赋给C程序里的变量。这个变量本来应该是double类型的,通过强制类型转换赋给了整形变量i。既然有标量,显然还应该有矢量,否则矩阵就没法传了。看下面的程序:
[cpp] view plaincopy
这样,就通过mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的指针。
但是,还有个问题,如果输入的不是单个的数据,而是向量或矩阵,那该怎么处理呢 ?通过mxGetPr只能得到指向这个矩阵的指针,如果我们不知道这个矩阵的确切大小,就 没法对它进行计算。
为了解决这个问题,Matlab提供了两个函数mxGetM和mxGetN来获得传进来参数的行数 和列数。下面例程的功能很简单,就是获得输入的矩阵,把它在屏幕上显示出来:
[cpp] view plaincopy
编译完成后,用下面的命令测试一下:
[cpp] view plaincopy
还有就是若是数据不是二维的,可以通过下面的函数获得数据的维度个数(向量:1,矩阵:2,...)以及维度数组。
需要注意的是,在Matlab里,矩阵第一行是从1开始的,而在C语言中,第一行的序数为零,Matlab里的矩阵元素b(i,j)在传递到C中的一维数组data后对应于data[j*M+i] 。 输入数据是在函数调用之前已经在Matlab里申请了内存的,由于mex函数与Matlab共用同一个地址空间,因而在prhs[]里传递指针就可以达到参数传递的目的。但是,输出参数却需要在mex函数内申请到内存空间,才能将指针放在plhs[]中传递出去。由于返回指针类型必须是mxArray,所以Matlab专门提供了一个函数:mxCreateDoubleMatrix来实现内存的申请,函数原型如下:
mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)
m:待申请矩阵的行数
n:待申请矩阵的列数
为矩阵申请内存后,得到的是mxArray类型的指针,就可以放在plhs[]里传递回去了。但是对这个新矩阵的处理,却要在函数内完成,这时就需要用到前面介绍的mxGetPr。使用 mxGetPr获得指向这个矩阵中数据区的指针(double类型)后,就可以对这个矩阵进行各种操作和运算了。下面的程序是在上面的show.c的基础上稍作改变得到的,功能是将输出处理后的元素:
[cpp] view plaincopy
当然,Matlab里使用到的并不是只有double类型这一种矩阵,还有字符串类型、稀疏矩阵、结构类型矩阵等等,并提供了相应的处理函数。本文用到编制mex程序中最经常遇到的一些函数,其余的详细情况清参考Apiref.pdf。 另外,若是不是输出元素,申请内存之后要记得释放: mwSize *subScript;
subScript = (mwSize *)mxCalloc( numOfDim, sizeof( mwSize ) ); mxFree( subScript );
通过前面两部分的介绍,大家对参数的输入和输出方法应该有了基本的了解。具备了这些知识,就能够满足一般的编程需要了。但这些程序还有些小的缺陷,以前面介绍的re由于前面的例程中没有对输入、输出参数的数目及类型进行检查,导致程序的容错性很差,以下程序则容错性较好
[cpp] view plaincopy
在上面的异常处理中,使用了两个新的函数:mexErrMsgTxt和mxIsDouble。MexErrMsgTxt在给出出错提示的同时退出当前程序的运行。MxIsDouble则用于判断mxArray中的数据是否double类型。当然Matlab还提供了许多用于判断其他数据类型的函数,这里不加详述。
需要说明的是,Matlab提供的API中,函数前缀有mex-和mx-两种。带mx-前缀的大多是对mxArray数据进行操作的函数,如mxIsDouble,mxCreateDoubleMatrix等等。而带mx前缀的则大多是与Matlab环境进行交互的函数,如mexPrintf,mxErrMsgTxt等等。了解了这一点,对在Apiref.pdf中查找所需的函数很有帮助。 另外,需要注意的是,当代码的后缀名为.c的时候,需要一次性把变量声明完,且放在代码的最前面,后缀为.cpp不会出现这个问题。
常用的Mex函数一览表
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
总结
以上是生活随笔为你收集整理的Matlab C混合编程的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 程序员编程艺术第二章
- 下一篇: 编程艺术 二进制中1的个数