ip84
ip84

Reputation: 300

Determining mxClassID of mwSize at mex file

I'm using the mxCreateNumericMatrix function at my mex file:

mxArray *mxCreateNumericMatrix(mwSize m, mwSize n, mxClassID classid, mxComplexity ComplexFlag);

I want to get array of type mwSize. For that I need to determine if using mxUINT32_CLASS or mxUINT64_CLASS as classid.

I can determine it in runtime with if statement on sizeof(mwSize), but is there a more elegant way to determine the class ID of mwSize? Maybe some define that depends on the system which has one value or the other?

Just a matter of aesthetics.

BTW, at Fortran there is a function mxClassIDFromClassName: http://www.mathworks.com/help/matlab/apiref/mxclassidfromclassname.html

mwSize is used for among the other reasons, so that the mxCreateDoubleMatrix function will be portable. It is strange if no elegant solution exists for mxCreateNumericMatrix.

Edit:

As @Praetorian explained, in my case I have no reason to use the type that fits the system (32 or 64 bits), as I specifically prefer it to be 64-bit integer array, and I can define this size also in 32-bit system.

But on the other hand, I also want to return two indices to the array that I return. In my case, I know that the array itself is short, and I use uint16_T anyway, but if I wanted it to fit the mwIndex, I would have to use some macro (@Amro suggested some good options), because apparently, there is no function as mxCreateDoubleMatrix for integers (that fits the system).

To sum it up, @Praetorian helped me with my case in the comments below and @Amro gave probably the best options available for the general case.

Upvotes: 1

Views: 640

Answers (2)

Amro
Amro

Reputation: 124563

The goal of mxCreateNumericMatrix and other mxCreate* functions is to create an mxArray (MATLAB fundamental type). Such arrays can be returned to MATLAB from the MEX-function.

mwSize is just a typedef to a size_t type (might be different for 32-bit vs. 64-bit), which is not a valid MATLAB datatype (not part of mxClassID). If actually you want to create an array of mwSize, allocate memory in C the usual way mxMalloc (but I doubt this is what you want in this case).


As Praetorian notes, the actual C type to which mwSize and mwIndex are typedef'ed is determined by the flags you pass to the mex command (or the default value if you didnt explicitly specify one):

>> mex -largeArrayDims file.c
>> mex -compatibleArrayDims file.c

If we inspect the tmwtypes.h header file which gets included, here is the relevant block of code:

#ifdef MX_COMPAT_32
typedef int mwSize;
typedef int mwIndex;
typedef int mwSignedIndex;
#else
typedef size_t    mwSize;         /* unsigned pointer-width integer */
typedef size_t    mwIndex;        /* unsigned pointer-width integer */
typedef ptrdiff_t mwSignedIndex;  /* a signed pointer-width integer */
#endif

(Recall that size_t is itself platform-dependent).


As mentioned in the comments above, I think you are misinterpreting the documentation. mwIndex and mwSize are meant to be used when indexing into a matrix and when dealing with matrix sizes respectively when writing MEX-function (instead of using non-portable plain int). They do not have corresponding mxClassID (so you cannot create mxArray's of those types and pass them back to MATLAB).

Now if you want to create an array of indices and return it to MATLAB to be used as a regular variable, you could create an mxArray of the equivalent type to unsigned integers (matching the bit-ness of your architecture: 32-bit vs 64-bit). Use macros to determine which one you are compiling for, and use mxUINT32_CLASS or mxUINT64_CLASS accordingly.

For example, we could use the same macro MATLAB is using:

#ifdef MX_COMPAT_32
typedef mxUINT32_CLASS INDICES_CLASS;
#else
typedef mxUINT64_CLASS INDICES_CLASS;
#endif

mxArray *arr = mxCreateNumericMatrix(10, 1, INDICES_CLASS, mxReal);
// ... fill arr with indices

Upvotes: 3

horchler
horchler

Reputation: 18484

Have you tried mxClassIDFromClassName in C? According to this list of undocumented libmx functions discussed here, it seems to exist. But yes, if you want to stick to what is listed in the online documentation, I don't know of a way other than using an if statement. Creating things other than double matrices in mex is always messier.

Upvotes: 0

Related Questions