fdermishin
fdermishin

Reputation: 3686

How can I check if mxArray has class type?

I need to compute the hash function of some variables inside mex function. Particularly I need to process a variable that is 24x1 geopoint vector. To do this I need to check its class, because there could be any variables as input, so I compute it using mxGetClassID. However, mxGetClassID returns value 1437, which doesn't correspond to any documented value in mxClassID, neither it is mxOBJECT_CLASS, which could be reasonable. I've also tried mxIsObject, but it returns false.

I have implemented the hash function for arrays, structures and cell arrays, and they all need different processing, but I'm stuck with classes. So how can I check if the given variable is an object?

UPD:

If I run mxGetClassName function from mex or class function from MATLAB Command Window for that variable, they both return "geopoint", but there is no info whether it is an object or not.

The function code is below:

void appendMxArrayHash(const mxArray* array, uint64& hash) {
    mxClassID classID = mxGetClassID(array);

    char buf[100];
    sprintf(buf, "classID '%d' in appendMxArrayHash", classID);
    mexWarnMsgIdAndTxt("MATLAB:NotImplemented", buf);

    appendHash(classID, hash);
    switch (classID) {
        case mxINT8_CLASS:
        case mxUINT8_CLASS:
        case mxINT16_CLASS:
        case mxUINT16_CLASS:
        case mxINT32_CLASS:
        case mxUINT32_CLASS:
        case mxINT64_CLASS:
        case mxUINT64_CLASS:
        case mxSINGLE_CLASS:
        case mxDOUBLE_CLASS:

        case mxCHAR_CLASS:
        {
            int n = mxGetN(array);
            int m = mxGetM(array);
            void* data = mxGetData(array);
            int elementSize = mxGetElementSize(array);

            appendHash(n, hash);
            appendHash(m, hash);
            appendHash(n * m * elementSize, (char*)data, hash);
            break;
        }
        case mxCELL_CLASS:
        {
            int n = mxGetN(array);
            int m = mxGetM(array);

            appendHash(n, hash);
            appendHash(m, hash);
            for (int i = 0; i < n * m; i++) {
                mxArray* cell = mxGetCell(array, i);
                appendMxArrayHash(cell, hash);
            }
            break;
        }
        case mxSTRUCT_CLASS:
        {
            int n = mxGetN(array);
            int m = mxGetM(array);
            int nFields = mxGetNumberOfFields(array);

            appendHash(n, hash);
            appendHash(m, hash);
            for (int i = 0; i < nFields; i++) {
                const char* name = mxGetFieldNameByNumber(array, i);
                int nameLength = strlen(name);
                appendHash(nameLength, hash);
                appendHash(nameLength, name, hash);
                for (int j = 0; j < n * m; j++) {
                    mxArray* field = mxGetFieldByNumber(array, j, i);
                    if (field)
                        appendMxArrayHash(field, hash);
                    else {
                        appendHash(0, hash);
                    }
                }
            }
            break;
        }
        default:
        {
            char buf[100];
            sprintf(buf, "Unsupported classID '%d' in appendMxArrayHash", classID);
            mexWarnMsgIdAndTxt("MATLAB:NotImplemented", buf);
        }
    }
}

UPD2:

That is array variable looks like:

trackSegment = 

 24x1 geopoint vector with properties:

 Collection properties:
     Geometry: 'point'
     Metadata: [1x1 struct]
 Feature properties:
     Latitude: [1x24 double]
    Longitude: [1x24 double]
    Elevation: [1x24 double]
         Time: {1x24 cell}

Upvotes: 2

Views: 824

Answers (1)

fdermishin
fdermishin

Reputation: 3686

I've finally figured out how to check variable. For some reason there is no alternative to isobject in mex. mxIsClass doesn't fit because it requires class name, which is unknown, as was mentioned in comments. So I just used mexCallMATLAB to call isobject.

The code is rather ugly and not the most effecient, however it works:

mxArray* isobjectResult = mxCreateNumericMatrix(1, 1, mxLOGICAL_CLASS, mxREAL);
mexCallMATLAB(1, &isobjectResult, 1, const_cast<mxArray**>(&array), "isobject");
if (mxIsLogicalScalarTrue(isobjectResult)) {
    // process array ...
}

Upvotes: 2

Related Questions