0

我用 C/C++ 创建了一个模拟器,它应该以 .mat 文件的形式输出结果,该文件可以导入到 Matlab 中的一些可视化工具中。

在模拟过程中,结果存储在数据缓冲区中。缓冲区为 a std::map<const char *, double *>,其中字符串应与对应的 matlab struct 字段同名,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
4

1 回答 1

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

于 2014-11-05T17:11:09.423 回答