Reputation: 3686
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
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