The Method of Mixed Programming with Matlab and C/C++

Matlab has strong numerical calculation and analysis capabilities, and C/C++ is currently the most popular high-level programming language. The complementary combination of the two hybrid programming is of great significance in scientific research and engineering practice.

1. Matlab calls C/C++

There are two main ways for Matlab to call C/C++: using MEX technology or calling C/C++ dynamic link library.

Before the mixed programming of Matlab and C/C++, the correct settings must be made for the compiling application mex of Matlab and the compiler mbuild:

Settings for Matlab compilation application mex:

Mex –setup

Settings for the Matlab compiler mbuild:

Mbuild –setup

1.1 Call the Mex file of C/C++

MEX is the abbreviation of Matlab Executable, which is a "C (or Fortran) language derivative program that can be called in Matlab" [6]. The use of MEX file is extremely convenient, its calling method is exactly the same as Matlab's built-in function, just type the MEX file name at the Matlab command prompt.

A C/C++ MEX source program usually includes 4 components, of which the first 3 are the content that must be included, and the fourth one is flexibly selected according to the realized function:
(1)#include “mex.h”;
(2 ) The entry function mexFunction of the MEX file, and the export name of the MEX file must be the mexFunction function;
(3)mxArray;
(4)API function;

A simple example is used to illustrate the C/C++ MEX source program writing and calling process (hello.c):

#include "mex.h" 
void mexFunction(int nlhs, mxArray *plhs[], 
int nrhs, const mxArray *prhs[]) 
{
    
     
    int *i; 
    i=mxGetPr(prhs[0]); 
    if(i[0]==1) 
      mexPrintf("hello,world!/n"); 
    else 
      mexPrintf("大家好!/n"); 
}  

Simply, the entire program consists of an interface sub-procedure mexFunction.
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])

**nlhs: number of output parameters
plhs: pointer to output parameters
nrhs: number of input parameters
plhs: pointer to input parameters
**

For example, use

[a,b]=test(c,d,e)

When calling the mex function test, the four parameters passed to test are

  2,plhs,3,prhs

among them:

prhs[0]=c 
prhs[1]=d 
prhs[2]=e 

When the function returns, the addresses you put in plhs[0], plhs[1] will be assigned to a and b to achieve the purpose of returning data.

Careful you may have noticed that both prhs[i] and plhs[i] are pointers to data of type mxArray. This type is defined in mex.h. In fact, most data in Matlab exists in this type. Of course, there are other data types, you can refer to the introduction in Apiguide.pdf .

Then put hello.c in the current execution directory of Matalb:

mex hello.c

After compiling this program, execute hello(1) on the command line, and it will be printed on the screen:

  hello,world! 

And hello(0) will get:

   大家好! 

In this program, in addition to the screen output function mexPrintf (used almost exactly the same as the printf function in c), a function is also used: mxGetScalar , the calling method is as follows:
i=mxGetScalar(prhs[0]);

Scalar means scalar. In Matlab, data exists in the form of an array. The function of mxGetScalar is to assign the data (scalar) pointed to by the pointer of the mxArray type passed in through prhs[0] to the variable in the C program. This variable was supposed to be of type double, and was assigned to the integer variable i through forced type conversion. Since there is a scalar, obviously there should be a vector, otherwise the matrix cannot be passed. Look at the following program:

//show.c  
#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"); 
    }
} 

After the compilation is complete, test it with the following command:

  a=1:10; 
  b=[a;a+1]; 
  show(a) 
  show(b) 

It should be noted that in Matlab, the first row of the matrix starts from 1, while in C language, the ordinal number of the first row is zero, and the matrix element b(i,j) in Matlab is transferred to C The large data of the one-dimensional array corresponds to data[j*M+i].

The input data has been applied for memory in Matlab before the function is called. Since the mex function and Matlab share the same address space, passing the pointer in prhs[] can achieve the purpose of parameter transfer. However, the output parameters need to apply for memory space in the mex function to pass the pointer in plhs[]. Since the return pointer type must be mxArray, Matlab specifically provides a function: mxCreateDoubleMatrix to realize the memory application, the function prototype is as follows:
mxArray * mxCreateDoubleMatrix(int ​​m, int n, mxComplexity ComplexFlag)

m: the number of rows of the matrix to be applied for
n: the number of columns of the matrix to be applied for

After applying memory for the matrix, you get a pointer of type mxArray, which can be passed back in plhs[]. However, the processing of this new matrix must be completed in the function, and the mxGetPr introduced earlier is needed. After using mxGetPr to obtain a pointer (double type) to the data area in this matrix, you can perform various operations and calculations on this matrix. The following program is slightly changed on the basis of show.c above:

//reverse.c 
#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]; 
} 

Of course, what is used in Matlab is not only the double type matrix, but also string type, sparse matrix, structure type matrix, etc., and provides corresponding processing functions. This article uses some of the most frequently encountered functions in compiling mex programs. For the rest of the details, please refer to Apiref.pdf.

Through the introduction of the previous two parts, everyone should have a basic understanding of parameter input and output methods. With this knowledge, you can meet the general programming needs. However, these programs still have some minor flaws. The re-introduced re, because the number and types of input and output parameters are not checked in the previous routines, leads to poor fault tolerance of the program. The following programs have better fault tolerance:

#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]; 
} 

In the above exception handling, two new functions are used: mexErrMsgTxt and mxIsDouble. MexErrMsgTxt exits the current program while giving an error prompt. MxIsDouble is used to determine whether the data in mxArray is of double type. Of course, Matlab also provides many functions for judging other data types, which are not detailed here.

It should be noted that in the API provided by Matlab, the function prefixes are mex- and mx-. The prefixes with mx- are mostly functions that operate on mxArray data, such as mxIsDouble, mxCreateDoubleMatrix, and so on. The prefixes with mx are mostly functions that interact with the Matlab environment, such as mexPrintf, mxErrMsgTxt and so on. Knowing this, it is very helpful to find the required function in Apiref.pdf.

Guess you like

Origin blog.csdn.net/daijingxin/article/details/111322716