Use of a user defined pointer to mxArray.

This has always bugged me about working with MEX-functions. Here is how I always end up working with the return argument from a MEX- function.
plhs[0] = mxCreateNumericArray(I,J,mxDOUBLE_CLASS,mxREAL);
for (ii=0;ii<M;ii++)
mxGetPr(plhs[0])[ii] = mxGetPr(prhs[0])[ii];
This works fine, but what I would like to do is find a way to not have to call mxGetPr every time through each and every loop in the file. To this end I tried this (starting with lhs):
mxArray *Ar; // initialize at beginning of file.
plhs[0] = mxCreateNumericArray(I,J,mxDOUBLE_CLASS,mxREAL); // SWITCH
Ar = mxGetPr(plhs[0]);// What is the point of this if I can't use it?
for (ii=0;ii<M;ii++)
*(Ar+ii) = mxGetPr(prhs[0])[ii];
But I get compile errors referencing: 'mxArray *' : unknown size.
The problem is that the return type is not known at compile time, so is there no way around using mxGetPr in such a case? I have had similar errors when working only with the prhs.
Thanks.

 Accepted Answer

The value replied by mxGetPr is a pointer to the data of the mxArray and therefore a (double *). (mxArray *) is a pointer to a struct. In consequence this does not work:

mxArray *Ar;             % **wrong**
Ar = mxGetPr(plhs[0]);   % **wrong**

Correct:

double *Ar;
Ar = mxGetPr(plhs[0]);

Or equivalent:

Ar = (double *) mxGetData(plhs[0]);

Modern compilers use the fast SSE unit to copy memory blocks in chunks of 128 or 256 bits, if you call MEMCPY. Therefore I suggest this:

plhs[0] = mxCreateNumericArray(I,J,mxDOUBLE_CLASS,mxREAL);
memcpy(mxGetPr(plhs[0]), mxGetPr(prhs[0]), M * sizeof(double));

8 Comments

For others -especially less experienced programmers-, who have similar questions, I'd suggest reading "doc mxGetPr" and "doc mxGetData".
Thanks, Jan.
I was thinking that since I don't know the data type of the lhs at compile time (as mentioned above), I couldn't use this in general:
double *Ar;
Ar = mxGetPr(plhs[0]);
Because that would make a pointer to double data only. Am I wrong about that?
Matt: mxGetPr is meant to be used only on data of type double. As the doc recommends "Use mxIsDouble to validate the mxArray type. For other mxArray types, use mxGetData."
mxGetData returns a void pointer which you can cast to the appropriate pointer type. To determine the datatype of an mxArray, you can use mxGetClassID.
If you don't know the data type at compile time you can use:
void *Ar;
:
Ar = mxGetData(etc);
Then you can use mxGetElementSize to determine the number of bytes per element and use that in a subsequent copy.
For your particular example, also look into the mxDuplicateArray function.
Thanks James, that is what I was looking for! I will give it a try later. Also, the thought occurred to me, I could put the initialization of Ar in the switch which evaluates on the datatype of the input argument, I think. I got so used to putting declarations at the beginning of the function that I started thinking it was a rule. But I saw a c++ example where the declaration was in the middle of the function. Maybe C is different. I will try this too. That would make it easier because then I could just do:
double *Ar;
or
float *Ar;
in the switch itself...
The copy was just an example, I did know about mxDuplicateArray and memcopy.
I will post if both of these methods work later...
As far as putting variable declarations in the middle of your code, that works in C as well but it is going to depend on how up-to-date your compiler is. It may not be portable.
@ James,
I am using (as I think you know ;)) VC++ 2010 express.
Thanks.
Thanks to all who helped. Both solutions above worked well...

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB Compiler in Help Center and File Exchange

Tags

Asked:

on 28 Apr 2011

Community Treasure Hunt

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

Start Hunting!