0

Matlab のいくつかの視覚化ツールにインポートできる .mat ファイルに結果を出力することになっている C/C++ でシミュレーターを作成しました。

シミュレーション中、結果はデー​​タ バッファーに格納されます。バッファーは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 のサポートは、問題の原因を特定するのに役立ちました。私のアプリケーションはブースト 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

最後に、作成した 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

したがって、すべてが正常に実行されます (Windows x64 で MATLAB R2014a を使用しています)。

于 2014-11-05T17:11:09.423 に答える