У меня есть симулятор в 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).