Berk U.
Berk U.

Reputation: 7198

Accessing matrices stored inside of cell arrays using MEX files in MATLAB

I am currently writing a MEX function that will have to work with a cell array in MATLAB. The MEX file is written in C.

Essentially, the input to my function will be a cell array where each entry is a numeric matrix with real values. A simple example is:

C = cell(1,2);
C{1} = ones(10,10);
C{2} = zeros(10,4);

I would like to be able to access the numeric arrays C{1} and C{2} in my MEX file. Ideally, I would like to do this without having to create a second copy of the data in my MEX File (i.e. get pointers for them).

Using the previous example, my current approach is as follows:

/* declare a pointer variable to the incoming cell array after it is passed to the MEX function */
mxArray C_CELL = (mxArray *) mxGetData(prhs[0]) 

/* declare  a 2 x 1 array of pointers to access the cell array in C */
double *myarray[2] //

/* point towards the contents of C_CELL */
myarray[0] = mxGetPr(C_CELL[0])
myarray[1] = mxGetPr(C_CELL[1])

Unfortunately this seems to yield "invalid use of undefined type 'struct mxArray_tag'" errors.

Upvotes: 3

Views: 2822

Answers (2)

David Heffernan
David Heffernan

Reputation: 613461

You need to use mxGetCell to extract the contents of a cell array.

mxArray *cellArray[2];
cellArray[0] = mxGetCell(prhs[0], 0);
cellArray[1] = mxGetCell(prhs[0], 1);

Upvotes: 6

mbauman
mbauman

Reputation: 31362

Lots of issues in that code sample:

  • You're missing trailing semicolons on every single line
  • mxArrays must be defined as pointers: e.g., mxArray *C_CELL.

But based upon the error message you're getting, I suppose you have those items correct in the source you're using.

Your main problem is that you're assigning the output of mxGetData to an mxArray *. The way mxGetData works is that it returns a raw (void *) pointer to your matrix contents. In this case, your matrix contains an array of mxArray pointers, with two levels of pointer redirection.

As such, C_CELL must be defined as mxArray **C_CELL. Note that doing this without any sanity checks or bound checking will rapidly lead to segfaults. Using mxGetCell as @David Heffernan suggests is a safer and more surefire way to do this (assuming you've checked that your prhs[0] contains a cell array).

Upvotes: 4

Related Questions