Gli elementi principali di un file mex in Matlab, scritto in linguaggio C/C++, sono principalmente quattro
- l'header mex.h
- il gateway mexFunction
- Gli array mxArray
- Le API function
mex.h
#include mex.h
Ogni mex-file scritto in C/C++ deve avere una direttiva di inclusione del header mex.h, in modo da poter utilizzare le API nella forma delle routines mx*
Il gateway mexFunction
mexFunction(int nlhs, mxArray *plhs[ ], int nrhs,
const mxArray *prhs[ ])
{
...
}
La routine di gateway tra il file mex e Matlab è chiamata mexFunction e, sostanzialmente, costituisce il "main" della libreria che andiamo ad implementare.
Tale routine, dichiarata il cui prototipo è dichiarato in mex.h, presenta i seguenti elementi:
- nlhs è il numero di mxArray in uscita (lhs - left hand side)
- plhs è un array di puntatori agli mxArray delle uscite attese
- nrhs è il numero di ingressi (rhs - right hand side)
- prhs è l'array di puntatori agli mxArray dei dati di ingresso, che sono read-only (const)
Si noti che il suffisso dei nomi di queste variabili si riferisce alla loro usuale posizione in una chiamata di funzione nell'ambiente Matlab. All'avvio dell'esecuzione del codice contenuto nel mex-file, i puntatori in plhs sono indefiniti, in quanto è compito del programma definirli esplicitamente (il compilatore non si occuperà di controllare se ciò avvenga).
mxArray
Si tratta di una struttura dati che gestisce i dati del programma e costituisce la rappresentazione in C dei vettori/matrici/string/cell di Matlab
Un mxArray viene dichiarato come una qualsiasi variabile
mxArray *myarray;
ma occorre che esso sia inizializzato con una mx* routine prima di essere usato (ad esempio, mxCreateNumericArray). Si noti che i dati in un mxArray vengono letti/scritti secondo il tipico ordine di Matlab, ovvero in colonna e verso destra, a differenza del C/C++ che li legge in riga e verso il basso.
Le API functions
Le API function prevedono, tra l'altro, le funzionalità per il trasferimento dei dati tra i mex-file e Matlab, la possibilità di richiamare funzioni Matlab dal codice sorgente in C/C++ e l'accesso ai dati contenute in un mxArray. Quelle più usate sono relative alla:
- creazione di array (mxCreateNumericArray, mxCreateCellArray, mxCreateCharArray);
- accesso agli array (mxGetPr, mxGetPi, mxGetM, mxGetM, mxGetData, mxGetCell)
- modifiche agli array (mxSetPr, mxSetPi, mxSetData, mxSetField)
- controllo di un array (mxIsClass)
- gestione della memoria (mxMalloc, mxCalloc, mxFree, mexMakeMemoryPersistent, mexAtExit, mxDestroyArray, memcpy)
- altro (mexEvalString, mexCallMATLAB, mexPrintf, mexWarnMsgTxt )
Una descrizione completa è reperibile in
MATLAB External/API Reference Guide.
Di seguito presentiamo un esempio di un mex-file che creare un mxArray per contenere i dati in uscita
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
int i, j, m, n;
double *data1, *data2;
if (nrhs != nlhs)
mexErrMsgTxt("The number of input and output arguments must be the same.");
for (i = 0; i < nrhs; i++)
{
/* Find the dimensions of the data */
m = mxGetM(prhs[i]);
n = mxGetN(prhs[i]);
/* Create an mxArray for the output data */
plhs[i] = mxCreateDoubleMatrix(m, n, mxREAL);
/* Retrieve the input data */
data1 = mxGetPr(prhs[i]);
/* Create a pointer to the output data */
data2 = mxGetPr(plhs[i]);
/* Put data in the output array */
for (j = 0; j < m*n; j++)
{
data2[j] = 2 * data1[j];
}
}
}
Altri esempi sono reperibili qui.