0

I have a created a simulator in C/C++ that is supposed to output the results in a .mat file that can be imported into some visualization tools in Matlab.

During the simulation results are stored in a data buffer. The buffer is a std::map<const char *, double *>, where the string should be the same name as the corresponding matlab struct field, and the double* is the buffered data.

At the end of the simulation I then use the following code to write the buffered data into a .mat file

const char **fieldnames; // Declared and populated in another class method
int numFields; // Declared in another method. Equal to fieldnames length.
int buffer_size; // Declared in another method. Equal to number of timesteps in simulation.

std::map<const char *, double *> field_data;
std::map<const char *, mxArray *> field_matrices;

// Open .mat file
MATFile *pmat = matOpen(filename.str().c_str(), "w");

// Create an empty Matlab struct of the right size
mxArray *SimData_struct = mxCreateStructMatrix(1,1,this->numFields,this->fieldnames);

int rows=this->buffer_size, cols=1;

for(int i=0; i<this->numFields; i++) {

   // Create an empty matlab array for each struct field
   field_matrices[this->fieldnames[i]] = mxCreateDoubleMatrix(rows, cols, mxREAL);

   // Copy data from buffers to struct fields
   memcpy(mxGetPr(field_matrices[this->fieldnames[i]]), this->field_data[this->fieldnames[i]], rows * cols * sizeof(double));

   // Insert arrays into the struct
   mxSetField(SimData_struct,0,this->fieldnames[i],field_matrices[this->fieldnames[i]]);

}

matPutVariable(pmat, object_name.str().c_str(), SimData_struct);

I can compile and start the simulation, but it dies with an error when the matPutVariable command is reached. The error I get is terminate called after throwing an instance of 'matrix::serialize::WrongSize'. I have tried to google for more information, but have been unable to find something that could help me.


Mathworks support helped me to identify the cause of the issue. My application uses boost 1.55, but Matlab uses 1.49. There was a clash between those dependencies that was solved by adding an additional external dependencies directory path.

-Wl,-rpath={matlab path}/bin/glnxa64
Jongware
  • 22,200
  • 8
  • 54
  • 100
Fabian Jonsson
  • 131
  • 1
  • 9

1 Answers1

1

I tried to reproduce the error with a simple example, but I don't see the problem. Here is my code:

test_mat_api.cpp

#include "mat.h"
#include <algorithm>

int main()
{
    // output MAT-file
    MATFile *pmat = matOpen("out.mat", "w");

    // create a scalar struct array with two fields
    const char *fieldnames[2] = {"a", "b"};
    mxArray *s = mxCreateStructMatrix(1, 1, 2, fieldnames);

    // fill struct fields
    for (mwIndex i=0; i<2; i++) {
        // 10x1 vector
        mxArray *arr = mxCreateDoubleMatrix(10, 1, mxREAL);
        double *x = mxGetPr(arr);
        std::fill(x, x+10, i);

        // assign field
        mxSetField(s, 0, fieldnames[i], arr);
    }

    // write struct to MAT-file
    matPutVariable(pmat, "my_struct", s);

    // cleanup
    mxDestroyArray(s);
    matClose(pmat);

    return 0;
}

First I compile the standalone program:

>> mex -client engine -largeArrayDims test_map_api.cpp

Next I run the executable:

>> !test_map_api.exe

Finally I load the created MAT-file in MATLAB:

>> whos -file out.mat
  Name           Size            Bytes  Class     Attributes

  my_struct      1x1               512  struct              

>> load out.mat

>> my_struct
my_struct = 
    a: [10x1 double]
    b: [10x1 double]

>> (my_struct.b)'
ans =
     1     1     1     1     1     1     1     1     1     1

So everything runs successfully (I'm using MATLAB R2014a on Windows x64).

Amro
  • 123,847
  • 25
  • 243
  • 454
  • Thanks for looking into it. It was originally a colleague of mine who wrote the code. He wrote a simple script just to try it out, and I incorporated it into the actual application. For him it worked, but not for me. Very strange. I will continue to work on it and see if I can figure it out. – Fabian Jonsson Nov 06 '14 at 08:53
  • Just to clarify, I get the same error when I run your code. Have not tried it in a new (empty) project though. Might be an idea. – Fabian Jonsson Nov 06 '14 at 09:39
  • @FabianJonsson: The code above works fine for me, so maybe you have a problem elsewhere in your code... Is your application multi-threaded? I ask because the MAT and MX APIs are not thread-safe. – Amro Nov 06 '14 at 20:47