How to read back (and use) a matrix from a matlab function called from a mex file?

2 visualizzazioni (ultimi 30 giorni)
I want to read back a matrix from a matlab function called from a mex file and I have been getting a segmentation violation when I try to run it. (At least my assumption is that it is related to how I am reading the matrix; I'm not exactly sure)
Here is an example representing what I am trying to do: (apologies if I include unnecessary detail, I am a novice mex user)
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]){
int ncols=210;
int mrows=210;
int i,j,
double ** a;
double ** b; // matrix to hold matlab output
mxArray * histforce_ips[1];
mxArray * histforce_ops[1];
// allocate memory:
a=(double**)malloc(mrows*sizeof(double *));
b=(double**)malloc(mrows*sizeof(double *));
for(i=0;i<mrows;i++){
a[i]=(double*)calloc(ncols,sizeof(double));
b[i]=(double*)calloc(ncols,sizeof(double));
}
// put something into a:
// ...
// pass a to matlab function
for(i=0;i<ncols;i++){
for(j=0;j<mrows;j++){
(mxGetPr(histforce_ips[0]))[i*mrows+j]=a[j][i];
}
}
// call function:
mexCallMATLAB(1,histforce_ops,1,histforce_ips,"calchistforce");
// extract data
for(i=0;i<ncols;i++){
for(j=0;j<mrows;j++){
b[j][i]=(mxGetPr(histforce_ops[0]))[i*mrows+j];
}
}
// free memory
for(i=0;i<mrows;i++){
free(a[i]);
free(b[i]);
}
free(a); free(b);
}
Thank you for your help.
N

Risposta accettata

James Tursa
James Tursa il 9 Apr 2013
Modificato: James Tursa il 9 Apr 2013
I don't see anywhere in your code where you create a variable in histforce_ips[0]. E.g.,
mxArray * histforce_ips[1];
:
mexCallMATLAB(1,histforce_ops,1,histforce_ips,"calchistforce");
There is nothing inbetween these lines that sets histforce_ips[0] to anything, so when you call mexCallMATLAB you are passing an invalid pointer for the input argument. You need to do something like this instead:
mxArray * histforce_ips[1];
:
histforce_ips[0] = mxCreateDoubleMatrix(mrows,ncols,mxREAL);
:
// Then fill in the values of histforce_ips[0] via mxGetPr etc
:
mexCallMATLAB(1,histforce_ops,1,histforce_ips,"calchistforce");
:
mxDestroyArray(histforce_ips[0]);
mxDestroyArray(histforce_ops[0]);
Also, I don't know if this will eventually make a difference in your code at some point, but the way you allocate your "a" and "b" matrices piecemeal means that the memory for them is not guaranteed to be contiguous. Generally, if you want to preserve the a[j][i] syntax of indexing I would recommend allocating a single block of memory and work with that instead. E.g.,
// allocate memory:
a=(double**)malloc(mrows*sizeof(double *));
b=(double**)malloc(mrows*sizeof(double *));
a[0] = (double *) malloc(mrows*ncols*sizeof(double));
b[0] = (double *) malloc(mrows*ncols*sizeof(double));
for(i=1;i<mrows;i++){
a[i] = a[i-1] + ncols;
b[i] = b[i-1] + ncols;
}
:
free(a[0]); free(a);
free(b[0]); free(b);
  3 Commenti
James Tursa
James Tursa il 9 Apr 2013
Please post your current code. It is critical where you create the variable. It needs to be done prior to accessing it in any way.
Nora
Nora il 10 Apr 2013
Thank you, I think what you suggested solved the problem. Now I am facing another problem, which is causing the segmentation error, but my posted minimal example isn't representative of this new issue (I haven't localized the issue yet). Thanks again, N

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Write C Functions Callable from MATLAB (MEX Files) in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by