Search code examples
c++matlabmex

Using mxGetPr vs mxGetData


I am trying to write a simple mex function. I have an integer input which is the number of my objects. When I compile myMEX_1.cpp and call it by MATLAB with any input value, I always get:

Number of Requested Objects := 0

But the myMEX_2.cpp works fine and show the number inputted from MATLAB command window. Where is the my mistake in myMEX_1.cpp?

My enviroment: MATLAB R2013a and Microsoft SDK 7.1 compiler.

// myMEX_1.cpp
#include "mex.h" 
void mexFunction(int nlhs,       mxArray *plhs[], 
                 int nrhs, const mxArray *prhs[]) 
{

    char str11[100];
    unsigned short frameCount;
    //unsigned short *frameCountPtr;
    frameCount = (*((unsigned short*)mxGetData(prhs[0])));
    sprintf(str11, "Number of Requested Objects := %d:\n", frameCount);
    mexPrintf(str11);
}





// myMEX_2.cpp
#include "mex.h" 
void mexFunction(int nlhs,       mxArray *plhs[], 
                 int nrhs, const mxArray *prhs[]) 
{
   char str11[100];
   unsigned short frameCount;
   double* dblPointer; 
   dblPointer = mxGetPr(prhs[0]);
   frameCount = (unsigned short)(*dblPointer);
   sprintf(str11, "Number of Requested Objects := %d:\n", frameCount);
   mexPrintf(str11);
}

Solution

  • mxGetData returns a void pointer which must be cast to a pointer of the correct datatype.

    In C, mxGetData returns a void pointer (void *). Since void pointers point to a value that has no type, cast the return value to the pointer type that matches the type specified by pm

    In your case, I'm assuming that although it looks like you've passed in an integer, it's actually a double since that is MATLAB's default datatype so your issue is due to the fact that you try to convert it to an unsigned short pointer.

    myMEX_1(1)          % Passes a double
    myMEX_1(uint16(1))  % Passes an integer
    

    To fix this, we would need to cast the output of mxGetData as a double pointer instead, and then dereference it, cast it and assign it

    frameCount = (unsigned short)*(double*)mxGetData(prhs[0]);
    

    mxGetPr is the same as mxGetData except that it automatically casts the output of mxGetData as a double pointer. Thus, it saves you a step but is only appropriate for double inputs (which you have).

    If you want to handle inputs of multiple types appropriately, you'll need to check the type of the input using either mxIsDouble or mxIsClass.

    if ( mxIsDouble(prhs[0]) ) {
        frameCount = (unsigned short)*mxGetPr(prhs[0]);
    } else if ( mxIsClass(prhs[0], "uint16") {
        frameCount = *(unsigned short*)mxGetData(prhs[0]);
    } else {
        mexPrintf("Unknown datatype provided!");
        return;
    }