MATLAB: Problem in using mxSetPr

mex

I am writing a function within in a mex file which calls a MATLAB function. Unfortunately, when it comes to mxSetPr, MATLAB crashes and does not proceed further. Could someone kindly tell me how I can fix this?
void myfun( double *Ain , double *Aout,
int AnRows , int AnCols,
double *kernel, int kernelnRows, int kernelnCols )
{
mxArray *rhs[3], *lhs[1];
rhs[0] = mxCreateNumericMatrix( 0, 0, mxDOUBLE_CLASS, mxREAL );
rhs[1] = mxCreateNumericMatrix( 0, 0, mxDOUBLE_CLASS, mxREAL );
rhs[2] = mxCreateString ( "same" );
mxSetPr( rhs[0], Ain );
mxSetM ( rhs[0], AnRows );
mxSetN ( rhs[0], AnCols );
mxSetPr( rhs[1], kernel );
mxSetM ( rhs[1], kernelnRows );
mxSetN ( rhs[1], kernelnCols );
mexCallMATLAB(1, lhs, 3, rhs, "conv2");
Aout = mxGetPr( lhs[0] );
}

Best Answer

AP - the documentation for mxSetPr indicates that for the second input parameter to this function,
The array must be in dynamic memory; call mxCalloc to allocate this memory. Do not use the ANSI® C calloc function, which can cause memory alignment issues leading to program termination. If pr points to static memory, memory leaks and other memory errors can result.
Did you use mxCalloc to allocate memory to Ain and kernel? That being said, I did try the following test function
void test()
{
mxArray* myMxArray = 0;
double* myDblArray = 0;
myMxArray = mxCreateNumericMatrix( 0, 0, mxDOUBLE_CLASS, mxREAL );
myDblArray = mxCalloc(4,sizeof(double));
if (myMxArray!=NULL && myDblArray!=NULL)
{
mxSetPr(myMxArray,myDblArray);
mxSetM(myMxArray,2);
mxSetN(myMxArray,2);
mxFree(myDblArray);
mxDestroyArray(myMxArray);
}
}
and the above crashed at the mxSetPr line. So I am a little puzzled by the above. James Tursa would most likely know what is wrong with the above code.
-------
The only time I've seen mxSetPr being used in for output (the lhs) of the mexFunction, so if I had to do something similar to what you are doing, I would have tried the following
void myfun2(double *Ain , int AnRows , int AnCols,
double *kernel, int kernelnRows, int kernelnCols,
mxArray **lhs)
{
mxArray *rhs[3];
double *ptr;
// create the mxArrays
rhs[0] = mxCreateNumericMatrix( AnRows, AnCols, mxDOUBLE_CLASS, mxREAL );
rhs[1] = mxCreateNumericMatrix( kernelnRows, kernelnCols, mxDOUBLE_CLASS, mxREAL );
rhs[2] = mxCreateString ( "same" );
// copy the Ain and kernel data
ptr = mxGetPr(rhs[0]);
memcpy(ptr,Ain,sizeof(double)*AnRows*AnCols);
ptr = mxGetPr(rhs[1]);
memcpy(ptr,kernel,sizeof(double)*kernelnRows*kernelnCols);
mexCallMATLAB(1, lhs, 3, rhs, "conv2");
// destroy the mxArrays
mxDestroyArray(rhs[0]);
mxDestroyArray(rhs[1]);
mxDestroyArray(rhs[2]);
}
Note in the above how memcpy is used to copy the data from the Ain and Kernel arrays to the destination mxArrays. Note also that for every create of an mxArray, we must destroy or free memory allocated to that array.
For the case of the left-hand side result of the convolution, we pass an mxArray into this function as
mxArray **lhs
As (presumably) memory will be dynamically allocated to it within the conv2 function, the caller of myfun2 does not need to allocate memory to this parameter, but the caller will be responsible for freeing the memory. For example,
// do some work to create the Ain and Kernel matrices
// declare the output matrix from the 2D convolution
mxArray *convMtx = 0;
// call the function to do the 2D convolution
myfun2(Ain, AnRows, AnCols,kernel,kernelnRows,kernelnCols,&convMtx);
if (convMtx!=NULL)
{
// do some stuff with convMtx
// destroy mxArray
mxDestroyArray(convMtx);
}
See how we pass the convMtx into the function as &convMtx.