matPutVariable:错误(matrix :: serialize :: WrongSize)尝试将数据输出到mat文件

时间:2014-11-05 15:15:01

标签: c++ c matlab mex mat-file

我在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

1 个答案:

答案 0 :(得分:1)

我尝试用一​​个简单的例子重现错误,但我没有看到问题。这是我的代码:

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;
}

首先我编译独立程序:

>> 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)。