MATLAB mexCallMatlab causes crash

I'm trying to develop a function in mex. The aim of the function should be sliding a window onto a 3D image and apply some function inside the window. Currently I'm stuck because when the algorithm reaches the call at the padarray function, MATLAB crashes.
So far I wrote these lines of code
#include <iostream>
#include "mex.h"
#include "matrix.h"
using namespace std;
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
#define O_IMAGE plhs[0]
#define I_IMAGE prhs[0]
#define I_PADSIZE prhs[1]
#define I_FUN prhs[2]
#define I_OPTION prhs[3]
// Argument Checking:
if(nrhs < 1 || nrhs > 4) /* Check the number of arguments */
mexErrMsgTxt("Wrong number of input arguments.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
// Variable declarations
static const char padding[] = "symmetric";
const char *windowShape;
const mwSize *dim;
mwSize *dimPad;
mwSize ndim;
double *pad, *windowSize, *thetaStep, *phiStep;
mxArray *inputFun[4], *inputPadFun[3], *input_image, *imagePad, *output_image;
/*Get dimensions of input image*/
ndim = mxGetNumberOfDimensions(I_IMAGE);
dim = mxGetDimensions(I_IMAGE);
/* Create dimensions of padded image*/
dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
dimPad = (mwSize *) memcpy((void *) dimPad,(void *) dim, ndim*sizeof(mwSize));
pad = mxGetPr(I_PADSIZE);
for (int i=0;i<ndim;++i)
{
dimPad[i] += 2*pad[i];
}
/*Get pointer to the input image*/
input_image = (mxArray *) mxGetData(I_IMAGE);
/* Create output image*/
O_IMAGE = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxREAL);
output_image = (mxArray *) mxGetData(O_IMAGE);
/* Create padded image*/
imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
// Padding input matrix
inputPadFun[0] = input_image;
inputPadFun[1] = (mxArray *)(pad);
inputPadFun[2] = (mxArray *)(padding);
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
// Clean UP
mxFree(dimPad);
mxDestroyArray(imagePad);
}
I checked the dimensions of the images in input and in output at mexCallMATLAB and they appear to be correct. I don't really understand what I'm doing wrong. Any help is greatly appreciated!

Answers (1)

James Tursa
James Tursa on 9 Sep 2015
Edited: James Tursa on 9 Sep 2015
I don't know if I caught everything, but here are some issues:
----------------------------
double *pad, *windowSize, *thetaStep, *phiStep;
:
inputPadFun[1] = (mxArray *)(pad);
pad is a pointer to double. You can't just cast this pointer to an mxArray pointer and expect the mxArray variable structure to be created for you. The way you have it, inputPadFun[1] still points to a bunch of doubles in memory. When MATLAB tries to access this memory location as an mxArray structure it will bomb for sure. I am not sure what you intend here, but if you want to use the doubles in pad for this argument, just use the original mxArray. E.g.,
inputPadFun[1] = (mxArray *) I_PADSIZE;
-----------------------
/*Get pointer to the input image*/
input_image = (mxArray *) mxGetData(I_IMAGE);
The result of the mxGetData call will be a pointer to the data area of I_IMAGE (i.e., prhs[0]). This does NOT point to an mxArray! So casting this pointer to an mxArray pointer will not work. Using it in mexCallMATLAB will crash MATLAB since MATLAB will attempt to read this memory as an mxArray structure when in fact it only contains the data of prhs[0].
------------------------
/* Create output image*/
O_IMAGE = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxREAL);
output_image = (mxArray *) mxGetData(O_IMAGE);
Same comment as above. You can't take a double * and simply cast it to an mxArray * and expect things to work downstream. If output_image ever got used in an API call, it would crash MATLAB.
-------------------------------
/* Create padded image*/
imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
:
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
imagePad will be created by the mexCallMATLAB function call ... it is not something you create ahead of time and pass into mexCallMATLAB. In fact, what you have above is a memory leak since the imagePad pointer value will get overwritten by the mexCallMATLAB call. Get rid of the imagePad = (etc) line.
------------------------------
static const char padding[] = "symmetric";
:
inputPadFun[2] = (mxArray *)(padding);
Similar comment as above. You can't simply cast a (char *) value into an (mxArray *) value and expect the mxArray structure to be created for you in the background. Even though inputPadFun[2] is an mxArray *, it still points to characters in memory and not an mxArray structure. You need to call an API function to turn this string into an mxArray variable. E.g.,
inputPadFun[2] = mxCreateString(padding);
And when you are done with the mexCallMATLAB call, destroy this temporary mxArray:
mxDestroyArray(inputPadFun[2]);
---------------------------
I don't see anything creating the plhs[0] data. plhs[0] gets created, but nothing is put in the data area. Was it your intent to return imagePad as plhs[0]?

Categories

Products

Asked:

on 9 Sep 2015

Edited:

on 9 Sep 2015

Community Treasure Hunt

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

Start Hunting!