У меня есть созданный симулятор в C / C ++, который должен выводить результаты в файл .mat, который можно импортировать в некоторые инструменты визуализации в Matlab.
Во время моделирования результаты сохраняются в буфере данных. Буфер является std::map<const char *, double *>
где строка должна иметь то же имя, что и соответствующее поле структуры matlab, а double * — это буферизованные данные.
В конце моделирования я затем использую следующий код для записи буферизованных данных в файл .mat.
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);
Я могу скомпилировать и запустить симуляцию, но она умирает с ошибкой при достижении команды matPutVariable. Я получаю ошибку terminate called after throwing an instance of 'matrix::serialize::WrongSize'
, Я пытался найти в Google дополнительную информацию, но не смог найти то, что могло бы мне помочь.
Поддержка Mathworks помогла мне определить причину проблемы. Мое приложение использует boost 1.55, но Matlab использует 1.49. Между этими зависимостями произошло столкновение, которое было решено путем добавления дополнительного пути к каталогу внешних зависимостей.
-Wl,-rpath={matlab path}/bin/glnxa64
Я попытался воспроизвести ошибку на простом примере, но не вижу проблемы. Вот мой код:
#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;
}
Сначала я компилирую отдельную программу:
>> mex -client engine -largeArrayDims test_map_api.cpp
Далее я запускаю исполняемый файл:
>> !test_map_api.exe
Наконец я загружаю созданный MAT-файл в 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
Так что все работает успешно (я использую MATLAB R2014a на Windows x64).