Question about assigning prhs to an int * in a mex file.
8 views (last 30 days)
Show older comments
Another silly question on mexFunction.
I tried the following code:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int *data = mxGetPr(prhs[0]);
mexPrintf("%f \n", data[0]);
}
If data is defined as
double* data = mxGetPr(prhs[0]);
what's printed out is correct.
If data is defined as the above
int* data = mxGetPr(prhs[0]);
what's printed out is always 0.000000, no matter what have been stored in "prhs".
Does that mean, for mexFunction, the unique way to cope with data is
double *data = mxGetPr(prhs[0]);
and I have to re-assign the data in different format by myself?
0 Comments
Answers (2)
Bård Skaflestad
on 22 Jan 2011
The mxGetPr() function always returns a pointer to double. Pointers to double are distinct from pointers to int and there exists no direct conversion between the two. Furthermore, the mxGetPr() function is only really applicable if the mxArray* satisfies either of mxIsDouble() or mxIsComplex(). If the mxArray* is any other data type (e.g., if mxIsInt32() returns true), then you must use the mxGetData() function to get at the actual data members of the mxArray*.
The solution to your problem depends a lot on the expected input to your mexFunction(). If you want to accept (arrays of) any MATLAB (numeric) data type (e.g., double or uint32), then you will typically have to allocate some memory for your int *data in your mexFunction() (see mxMalloc() or mxCreateNumericMatrix()) and then loop over the data members of the mxArray* to manually effect the type conversion.
5 Comments
Walter Roberson
on 25 Jan 2011
Jan, one of the oddities of C is that pointers to different types are allowed to be different lengths and use different representations. The only pointer conversion that is guaranteed is conversion to void* and conversion back to the same type -- this restriction explicitly defined in the C language.
You have also mixed together "int" (which Baard referenced) and int32_T . "int" is permitted to have an alignment smaller than 32 bits. Recall that traditionally "int" was a 16 bit quantity and it took "long int" to be sure of 32 or more bits.
Jan
on 25 Jan 2011
Dear Walter, thanks for the important information. As far as I can see, I did *not* mix "int" and "int32_T", because these terms appear in different sentences.
You are right: The ISO C++ standard says clearly that the typecasting between different pointer types depend on the compiler. E.g. the alignment can cause problems when casting char* to a long*.
On the other hand, do you know a compiler supported by Matlab, which replies different values for "(int *) mxGetPi" and "(int *) mxGetImagData"?
However, it seems like the OP has another problem: Either he tries to cast the value by casting the pointer type, or he calls he uses the "%f" format for an int value (or *she*).
Siddharth Shankar
on 26 Jan 2011
int *data = (int *) mxGetData(prhs[0]);
is what you need to do. mxGetData will return a void ptr which then needs to be "cast" appropriately.
3 Comments
Siddharth Shankar
on 26 Jan 2011
I would prefer an approach where mxIsClass is used to query the type of the incoming data and the data is then assigned appropriately after casting the output of mxGetData. But yes, there are plenty of ways to do this.
Bård Skaflestad
on 28 Jan 2011
Actually, if you're in C (*not* C++), then the output of |mxGetData()| (i.e., a |void*|) can be directly converted to a pointer to |int|. This is what Walter Roberson mentioned earlier. In other words, in the C programming language, explicitly converting a |void*| into an |int*| by means of a cast is not required and becomes purely a matter of personal style.
I prefer not to add the explicit cast myself.
See Also
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!