El método de programación mixta con Matlab y C / C ++

Matlab tiene sólidas capacidades de análisis y cálculo numérico, y C / C ++ es actualmente el lenguaje de programación de alto nivel más popular. La combinación complementaria de los dos programas híbridos tiene una importancia muy importante en la investigación científica y la práctica de la ingeniería.

1. Matlab llama a C / C ++

Hay dos formas principales para que Matlab llame a C / C ++: usando tecnología MEX o llamando a la biblioteca de enlaces dinámicos C / C ++.

Antes de la programación mixta de Matlab y C / C ++, se deben realizar los ajustes correctos para la aplicación de compilación mex de Matlab y el compilador mbuild:

Configuración de la aplicación de compilación Matlab mex:

Mex –setup

Configuración para el compilador de Matlab mbuild:

Mbuild –setup

1.1 Llamar al archivo Mex de C / C ++

MEX es la abreviatura de Matlab Executable, que es un "programa derivado del lenguaje C (o Fortran) que se puede llamar en Matlab" [6]. El uso del archivo MEX es extremadamente conveniente, su método de llamada es exactamente el mismo que la función incorporada de Matlab, simplemente escriba el nombre del archivo MEX en el símbolo del sistema de Matlab.

Un programa fuente C / C ++ MEX generalmente incluye 4 componentes, de los cuales los primeros 3 son el contenido que debe incluirse, y el cuarto se selecciona de manera flexible de acuerdo con la función realizada:
(1) #include “mex.h”;
(2 ) La función de entrada mexFunction del archivo MEX y el nombre de exportación del archivo MEX debe ser la función mexFunction;
(3) mxArray;
(4) función API;

Se utiliza un ejemplo simple para ilustrar el proceso de escritura y llamada del programa fuente MEX de C / C ++ (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"); 
}  

Simplemente, todo el programa consta de un subprocedimiento de interfaz mexFunction.
void mexFunction (int nlhs, mxArray * plhs [], int nrhs, const mxArray * prhs [])

** nlhs: número de parámetros de salida
plhs: puntero a parámetros de salida
nrhs: número de parámetros de entrada
plhs: puntero a parámetros de entrada
**

Por ejemplo, use

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

Al llamar a la prueba de función mex, los cuatro parámetros pasados ​​a prueba son

  2,plhs,3,prhs

entre ellos:

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

Cuando la función regrese, las direcciones que ingrese en plhs [0], plhs [1] se asignarán a ayb para lograr el propósito de devolver datos.

Con cuidado, habrá notado que tanto prhs [i] como plhs [i] son ​​punteros a datos de tipo mxArray. Este tipo se define en mex.h. De hecho, la mayoría de los datos en Matlab existen en este tipo. Por supuesto, existen otros tipos de datos, puede consultar la introducción en Apiguide.pdf .

Luego coloque hello.c en el directorio de ejecución actual de Matalb:

mex hello.c

Después de compilar este programa, ejecute hello (1) en la línea de comando y se imprimirá en la pantalla:

  hello,world! 

Y hola (0) obtendrá:

   大家好! 

En este programa, además de la función de salida de pantalla mexPrintf (usada casi exactamente igual que la función printf en c), también se usa una función: mxGetScalar , el método de llamada es el siguiente:
i = mxGetScalar (prhs [0]) ;

Escalar significa escalar. En Matlab, los datos existen en forma de matrices. La función de mxGetScalar es asignar los datos (escalares) apuntados por el puntero del tipo mxArray pasado a través de prhs [0] a la variable en el programa C. Se suponía que esta variable era de tipo double y se asignó a la variable entera i mediante una conversión de tipo forzada. Como hay escalares, obviamente también debería haber vectores, de lo contrario no se puede pasar la matriz. Mira el siguiente programa:

//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"); 
    }
} 

Una vez completada la compilación, pruébela con el siguiente comando:

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

Cabe señalar que en Matlab, la primera fila de la matriz comienza desde 1, mientras que en lenguaje C, el número ordinal de la primera fila es cero, y el elemento de la matriz b (i, j) en Matlab se transfiere a C. Los datos grandes de la matriz unidimensional corresponden a los datos [j * M + i].

Los datos de entrada se han aplicado a la memoria en Matlab antes de que se llame a la función. Dado que la función mex y Matlab comparten el mismo espacio de direcciones, pasar el puntero en prhs [] puede lograr el propósito de la transferencia de parámetros. Sin embargo, los parámetros de salida deben solicitar espacio de memoria en la función mex para pasar el puntero en plhs []. Dado que el tipo de puntero de retorno debe ser mxArray, Matlab proporciona específicamente una función: mxCreateDoubleMatrix para realizar la aplicación de memoria, el prototipo de la función es el siguiente:
mxArray * mxCreateDoubleMatrix (int m, int n, mxComplexity ComplexFlag)

m: el número de filas de la matriz que se aplicarán para
n: el número de columnas de la matriz que se aplicarán

Después de aplicar memoria para la matriz, obtiene un puntero de tipo mxArray, que puede devolverse en plhs []. Sin embargo, el procesamiento de esta nueva matriz debe completarse en la función y se necesita el mxGetPr introducido anteriormente. Después de usar mxGetPr para obtener un puntero (tipo doble) al área de datos en esta matriz, puede realizar varias operaciones y cálculos en esta matriz. El siguiente programa se ha modificado ligeramente sobre la base de show.c anterior:

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

Por supuesto, lo que se usa en Matlab no es solo la matriz de tipo doble, sino también el tipo de cadena, la matriz dispersa, la matriz de tipo de estructura, etc., y proporciona las funciones de procesamiento correspondientes. Este artículo utiliza algunas de las funciones más frecuentes en la compilación de programas mex. Para el resto de los detalles, consulte Apiref.pdf.

A través de la introducción de las dos partes anteriores, todos deben tener un conocimiento básico de los métodos de entrada y salida de parámetros. Con este conocimiento, puede satisfacer las necesidades generales de programación. Sin embargo, estos programas todavía tienen algunas fallas menores. El reintroducido, debido a que el número y los tipos de parámetros de entrada y salida no se verifican en las rutinas anteriores, conduce a una mala tolerancia a fallas del programa. :

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

En el manejo de excepciones anterior, se utilizan dos funciones nuevas: mexErrMsgTxt y mxIsDouble. MexErrMsgTxt sale del programa actual mientras da un mensaje de error. MxIsDouble se utiliza para determinar si los datos en mxArray son de tipo doble. Por supuesto, Matlab también proporciona muchas funciones para juzgar otros tipos de datos, que no se detallan aquí.

Cabe señalar que en la API proporcionada por Matlab, los prefijos de función son mex- y mx-. Los prefijos con mx- son principalmente funciones que operan con datos mxArray, como mxIsDouble, mxCreateDoubleMatrix, etc. Los prefijos con mx son principalmente funciones que interactúan con el entorno de Matlab, como mexPrintf, mxErrMsgTxt, etc. Sabiendo esto, es muy útil encontrar la función requerida en Apiref.pdf.

Supongo que te gusta

Origin blog.csdn.net/daijingxin/article/details/111322716
Recomendado
Clasificación