我在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'
。我试图谷歌获取更多信息,但一直无法找到可以帮助我的东西。
Mathworks支持帮助我确定问题的原因。我的应用程序使用boost 1.55,但Matlab使用1.49。通过添加额外的外部依赖项目录路径解决了这些依赖项之间的冲突。
-Wl,-rpath={matlab path}/bin/glnxa64
答案 0 :(得分:1)
我尝试用一个简单的例子重现错误,但我没有看到问题。这是我的代码:
#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
最后我在MATLAB中加载创建的MAT文件:
>> 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
所以一切都运行成功(我在Windows x64上使用MATLAB R2014a)。