简体   繁体   中英

How to access a matrix in a matlab struct's field from a mex function?

I'm trying to figure out how to access a matrix that is stored in a field in a matlab structure from a mex function.

That's awfully long winded... Let me explain:

I have a matlab struct that was defined like the following:

matrixStruct = struct('matrix', {4, 4, 4; 5, 5, 5; 6, 6 ,6})

I have a mex function in which I would like to be able to receive a pointer to the first element in the matrix (matrix[0][0], in c terms), but I've been unable to figure out how to do that.

I have tried the following:

/* Pointer to the first element in the matrix (supposedly)... */
double *ptr = mxGetPr(mxGetField(prhs[0], 0, "matrix");  

/* Incrementing the pointer to access all values in the matrix */
for(i = 0; i < 3; i++){  
    printf("%f\n", *(ptr + (i * 3)));
    printf("%f\n", *(ptr + 1 + (i * 3)));
    printf("%f\n", *(ptr + 2 + (i * 3)));
}

What this ends up printing is the following:

4.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000

I have also tried variations of the following, thinking that perhaps it was something wonky with nested function calls, but to no avail:

/* Pointer to the first location of the mxArray */
mxArray *fieldValuePtr = mxGetField(prhs[0], 0, "matrix");

/* Get the double pointer to the first location in the matrix */
double *ptr = mxGetPr(fieldValuePtr);

/* Same for loop code here as written above */

Does anyone have an idea as to how I can achieve what I'm trying to, or what I am potentially doing wrong?

Thanks!

Edit: As per yuk's comment, I tried doing similar operations on a struct that has a field called array which is a one-dimensional array of doubles.

The struct containing the array is defined as follows:

arrayStruct = struct('array', {4.44, 5.55, 6.66})

I tried the following on the arrayStruct from within the mex function:

mptr = mxGetPr(mxGetField(prhs[0], 0, "array"));

printf("%f\n", *(mptr));
printf("%f\n", *(mptr + 1));
printf("%f\n", *(mptr + 2));

...but the output followed what was printed earlier:

4.440000
0.000000
0.000000

struct('field', {abc}) is a special form of the struct constructor which creates a struct array that is the same size as the cell array, putting each element of the cell into field 'field' of the corresponding element of the struct. That is, this:

s = struct('field', {a b c});

produces the same result as this:

s(1).field = a;
s(2).field = b;
s(3).field = c;

The solution to your problem is to use square brackets to form a regular (non-cell) array, like this:

matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6]);

You are trying to access the variable which is cell array in MATLAB. Are you sure the data are stored consequently? What happens if you put double array into the structure?

matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6])

I think the problem is how MATLAB stores data in cell array. Try to run this:

double1 = 1;
double2 = 1:2;
cellempty = {[]};
celldouble1 = {1};
celldouble2 = {1:2};
cell2doubles = {1,2};
whos

The output:

Name              Size            Bytes  Class     Attributes
  cell2doubles      1x2               136  cell                
  celldouble1       1x1                68  cell                
  celldouble2       1x1                76  cell                
  cellempty         1x1                60  cell                
  double1           1x1                 8  double              
  double2           1x2                16  double              

You can see that each element of cell array occupy additional 60 bytes to the size of numbers.

I have been through this: I have a struct with a field which is a matrix. In C++ the corresponding structure is a double** for instance. Trying to access the field with engGetVariable(engine,MyStruct.theField) fails. I use a temp variable to store the MyStruct.theField and then use engGetVariable(engine, tempVar) , and code to get the matrix field from the struct looks like that

// Fetch struct field using a temp variable
std::string tempName = std::string(field_name) + "_temp";
std::string fetchField = tempName + " = " + std::string(struct_name) 
        + "." + std::string(field_name) + "; ";
matlabExecute(ep, fetchField);
mxArray *matlabArray = engGetVariable(ep, tempName.c_str());

// Get variable elements
const int count = mxGetNumberOfElements(matlabArray);
T *data = (T*) mxGetData(matlabArray);
for (int i = 0; i < count; i++)
    vector[i] = _isnan(data[i]) ? (T) (int) -9999 : (T) data[i];

// Clear temp variable
std::string clearTempVar = "clear " + tempName + "; ";
matlabExecute(ep, clearTempVar);

// Destroy mx object
mxDestroyArray(matlabArray);

Very similarly to set the matrix field to the struct I did that

// Create temp variable
mxArray* array = convertVectorToMxArray(mat, nb_rows, nb_cols);  
const std::string temp_name = array_name + "_temp";
int ret = engPutVariable(ep, temp_name.c_str(), array);

// Set variable to struct field
const std::string cmd = std::string(array_name + " = " + temp_name + "; ");
matlabExecute(ep, cmd);

// Delete array
mxDestroyArray(array);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM