欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Matlab C混合编程

发布时间:2025/4/16 编程问答 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Matlab C混合编程 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
设置编译器路径 在Matlab 命令窗口键入    mex -setup,下面只要根据提示一步步设置就可以了。 为了测试你的路径设置正确与否,把下面的程序存为hello.c。
[cpp] view plaincopy
  • #include "mex.h"  
  • void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])  
  • {  
  •    mexPrintf("hello,world!\n");  
  • }  

  • 假设你把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.c 2.0   
  • #include "mex.h"   
  • void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])   
  • {  
  • int i;   
  • i=mxGetScalar(prhs[0]);   
  • if(i==1)   
  •   mexPrintf("hello,world!\n");   
  • else   
  •   mexPrintf("大家好!\n");   
  • }  


  • 将这个程序编译通过后,执行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
  • //hello.c 2.1   
  • #include "mex.h"   
  • void mexFunction(int nlhs, mxArray *plhs[],   
  • int nrhs, const mxArray *prhs[])   
  • {   
  • int *i;   
  • i=mxGetPr(prhs[0]); //prhs是一个指针数组(每一个是一个指针),所以返回一个指针  
  • if(i[0]==1)   
  •   mexPrintf("hello,world!\n");   
  • else   
  •   mexPrintf("大家好!\n");   
  • }    


  • 这样,就通过mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的指针。
    但是,还有个问题,如果输入的不是单个的数据,而是向量或矩阵,那该怎么处理呢 ?通过mxGetPr只能得到指向这个矩阵的指针,如果我们不知道这个矩阵的确切大小,就 没法对它进行计算。 
    为了解决这个问题,Matlab提供了两个函数mxGetM和mxGetN来获得传进来参数的行数 和列数。下面例程的功能很简单,就是获得输入的矩阵,把它在屏幕上显示出来: 
    [cpp] view plaincopy
  • //show.c 1.0   
  • #include "mex.h"   
  • #include "mex.h"   
  • void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])   
  • {   
  • double *data;   
  • int M,N;   
  • int i,j;   
  • data=mxGetPr(prhs[0]); //获得指向矩阵的指针   
  • M=mxGetM(prhs[0]); //获得矩阵的行数   
  • N=mxGetN(prhs[0]); //获得矩阵的列数   
  • for(i=0;i<M;i++)   
  • {   for(j=0;j<N;j++)   
  •      mexPrintf("%4.3f  ",data[j*M+i]);   
  •      mexPrintf("\n");   
  •   }  
  • }   


  • 编译完成后,用下面的命令测试一下: 
    [cpp] view plaincopy
  • a=1:10;   
  • b=[a;a+1];   
  • show(a)   
  • show(b)   


  • 还有就是若是数据不是二维的,可以通过下面的函数获得数据的维度个数(向量:1,矩阵:2,...)以及维度数组。
  •     // 获取维度个数  
  •     numOfDim = mxGetNumberOfDimensions(pArray);  
  •     // 获取维度数组  
  •     Dims = mxGetDimensions(pArray);

  • 需要注意的是,在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
  • //reverse.c 1.0   
  • #include "mex.h"   
  • void mexFunction(int nlhs, mxArray *plhs[],   
  •     int nrhs, const mxArray *prhs[])   
  • {   
  • double *inData;   
  • double *outData;   
  • int M,N;   
  • int i,j;   
  • inData=mxGetPr(prhs[0]);   
  • M=mxGetM(prhs[0]);   
  • N=mxGetN(prhs[0]);   
  • plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL);   
  • outData=mxGetPr(plhs[0]);   
  • for(i=0;i<M;i++)   
  •   for(j=0;j<N;j++)   
  •    outData[j*M+i]=inData[(N-1-j)*M+i];   
  • }   


  • 当然,Matlab里使用到的并不是只有double类型这一种矩阵,还有字符串类型、稀疏矩阵、结构类型矩阵等等,并提供了相应的处理函数。本文用到编制mex程序中最经常遇到的一些函数,其余的详细情况清参考Apiref.pdf。  另外,若是不是输出元素,申请内存之后要记得释放: mwSize *subScript; 
    subScript = (mwSize *)mxCalloc( numOfDim, sizeof( mwSize ) );  mxFree( subScript ); 
    通过前面两部分的介绍,大家对参数的输入和输出方法应该有了基本的了解。具备了这些知识,就能够满足一般的编程需要了。但这些程序还有些小的缺陷,以前面介绍的re由于前面的例程中没有对输入、输出参数的数目及类型进行检查,导致程序的容错性很差,以下程序则容错性较好
    [cpp] view plaincopy
  • #include "mex.h"   
  • void mexFunction(int nlhs, mxArray *plhs[],  int nrhs, const mxArray *prhs[])   
  • {   
  • double *inData;   
  • double *outData;   
  • int M,N;   
  • //异常处理   
  • //异常处理   
  • if(nrhs!=1)   
  •     mexErrMsgTxt("USAGE: b=reverse(a)\n");   
  •   if(!mxIsDouble(prhs[0]))   
  •    mexErrMsgTxt("the Input Matrix must be double!\n");   
  •    inData=mxGetPr(prhs[0]);   
  •    M=mxGetM(prhs[0]);   
  •    N=mxGetN(prhs[0]);   
  •    plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL);   
  •    outData=mxGetPr(plhs[0]);   
  •    for(i=0;i<M;i++)   
  •      for(j=0;j<N;j++)   
  •      outData[j*M+i]=inData[(N-1-j)*M+i];   
  •   }   


  • 在上面的异常处理中,使用了两个新的函数: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混合编程的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。