Search code examples
c++matlabmatio

How can I load struct fields from Matlab to C++?


So I have a struct called stf with multiple fields; each field is a vector. I tried using the Matio library to get reach for those variables, but all I get is one variable, namely the struct stf. As the stf struct has 4 fields, I get 4 double variables. But how do I access the fields themselves? I want to store each of those fields in a vector in my C++ code.

For better understanding, here's my code:

int main(int argc, char** argv)
{
    mat_t* matfp;
    matvar_t* matvar;
    matfp = Mat_Open("fields.mat", MAT_ACC_RDONLY);
    if (NULL == matfp) {
        fprintf(stderr, "Error opening MAT file \"%s\"!\n", argv[1]);
        return EXIT_FAILURE;
    }
    matvar = Mat_VarRead(matfp, "stf");
    const double* xData = static_cast<const double*>(matvar->data);
    unsigned Size = matvar->nbytes / matvar->data_size;
    std::cout << "\n";
    for (int i = 0; i < matvar->rank; ++i)
    {
        std::cout << "\tdim[" << i << "] == " << matvar->dims[i] << "\n";
    }
    for (int i = 0; i < Size; ++i)
    {
        cout << "\tstf[" << i << "] = " << xData[i] << "\n";
    }

    Mat_Close(matfp);
    return EXIT_SUCCESS;
}

And here's the output I get:

      dim[0] == 1
      dim[1] == 1
      stf[0] = 1.3315e-311
      stf[1] = 1.3315e-311
      stf[2] = 1.3315e-311
      stf[3] = 1.3315e-311

And why are they all the same number? I am way over my head, any help would be appreciated.


Solution

  • Alright, I figured it out. I made a function that loads the struct fields and then stores them in a matrix from the Eigen library. t looks something like this:

    MatrixXd load(string workspace_name, const char* variable_name, const char* field_name)
    {
        const char* filename = workspace_name.c_str();
        mat_t* mat;
        matvar_t* matvar, * field;
        mat = Mat_Open(filename, MAT_ACC_RDONLY);
        matvar = Mat_VarReadInfo(mat, variable_name);
        field = Mat_VarGetStructFieldByName(matvar, field_name, 0);
        int read_err = Mat_VarReadDataAll(mat, field);
        MatrixXd C;
        C.resize(field->dims[0], field->dims[1]);
        unsigned Size = field->nbytes / field->data_size;
        const double* Data = static_cast<const double*>(field->data);
        int column = 0;
        int row = 0;
        for (int i = 0; i < Size; ++i)
        {
            if (row > C.rows() - 1) {
                row = 0;
                column += 1;
            }
            C(row, column) = Data[i];
            row += 1;
        }
    
        Mat_VarFree(matvar);
        Mat_Close(mat);
    
        return C;
    }