Main Content

入力と出力の処理

C++ MEX API は、引数へのアクセスと検証を可能にする機能を提供しています。matlab::mex::ArgumentListmatlab::data::Array はどちらも、MEX 関数に渡された引数のチェックに便利な関数を定義します。matlab::data::ArrayType 列挙型クラスを使用すると、特定の型の入力をテストできます。

引数の検証

以下の表は、エラー チェックに便利な関数を示しています。

matlab::mex::ArgumentList::size()入力の数を判定します。配列 ArgumentList のサイズは、関数呼び出しで使用されている引数の数に等しくなります。
matlab::mex::ArgumentList::empty()入力または出力がないことをテストします。入力関数または出力関数なしで MEX 関数が呼び出された場合、対応する ArgumentList 引数は空になります。
matlab::data::Array::getType()入力引数の型を判定します。この関数は、matlab::data::ArrayType オブジェクトを返します。
matlab::data::Array::getDimensions()入力引数配列の次元数を判定します。この関数は、std::vector<size_t> として定義される matlab::data::ArrayDimensions オブジェクトを返します。
matlab::data::Array::getNumberOfElements()入力引数配列の要素数を判定します。
matlab::data::Array::isEmpty()入力引数配列が空かどうかを判定します。

これらの例では、MEX ファイルで引数の値をテストして、テストが失敗した場合に MATLAB® でエラーをスローする方法を示します。関数 feval を使用して、MATLAB 関数 error または warning を呼び出します。

以下の引数を指定して feval を呼び出します。

  • UTF16 文字列として渡される、error または warning の関数名。

  • 返される引数の数。これらの例では 0 になります。

  • MATLAB 関数 error または warning で表示するメッセージ。matlab::data::ArrayFactory factory を使用して作成された matlab::data::Array が含まれる std::vector として、メッセージを渡します。

feval を呼び出して引数を定義するには、MATLAB エンジンと、MATLAB データ配列 factory へのポインターを取得します。

class MexFunction : public matlab::mex::Function {
public:
    void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
        std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
        matlab::data::ArrayFactory factory;
        ...
    }
}

MEX ファイルには 3 つの入力引数が必要です。

if (inputs.size() != 3) {
    matlabPtr->feval(u"error", 0,
        std::vector<matlab::data::Array>({ factory.createScalar("Three inputs required") }));
}

MEX ファイルには 2 つの出力引数の代入が必要です。

if (outputs.size() != 2) {
    matlabPtr->feval(u"error", 0, 
        std::vector<matlab::data::Array>({ factory.createScalar("Two outputs required") }));
}

2 番目の入力引数は、非複素数の double の 1 行 4 列のベクトルでなければなりません。

if (inputs[1].getType() != matlab::data::ArrayType::DOUBLE ||
    inputs[1].getType() == matlab::data::ArrayType::COMPLEX_DOUBLE ||
    inputs[1].getNumberOfElements() != 4 || 
    inputs[1].getDimensions()[1] == 1) {
    matlabPtr->feval(u"error", 0, 
       std::vector<matlab::data::Array>({ factory.createScalar("Input must be 4-element row vector")}));
}

ArgumentList 反復子

matlab::mex::ArgumentList コンテナーは、引数リストの最初と最後をマークする 1 対の反復子を実装します。これらの反復子を使用して、1 つの MEX 関数へのすべての入力にわたってループします。たとえば、この MEX 関数は、範囲ベースの for ループを使用して、すべての入力を合計します。

#include "mex.hpp"
#include "mexAdapter.hpp"

class MexFunction : public matlab::mex::Function {
    matlab::data::ArrayFactory factory;
public:
    void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
        double sm = 0;
        for (const matlab::data::TypedArray<double>& elem : inputs) {
            sm = sm + elem[0];
        }
        outputs[0] = factory.createScalar(sm);
    };
};

この MEX ファイルを sumInputs.cpp として保存し、mex コマンドでコンパイルします。さまざまな引数を使用して関数を呼び出します。

mex sumInputs.cpp
sumInputs(1,2,3,4,5,6,7)

ans =

    28

可変個の引数のサポート

入力および出力配列 matlab::mex::ArgumentList のサイズをチェックすることで、MEX 関数の引数の数が可変の場合をサポートします。

次のコード スニペットで、パラメーター配列 outputs のサイズは、MEX 関数が呼び出されたときに指定される出力の数を示します。コードは関数 ArgumentList::size を使用して、MEX 関数が呼び出されたときに指定される出力の数を判定します。

void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {

    if (outputs.size() == 3) {
        outputs[0] = // Assign first output
        outputs[1] = // Assign second output
        outputs[2] = // Assign third output
    }
    else if (outputs.size() == 1) {
        outputs[0] = // Assign only one output
    }
    else {
        matlabPtr->feval(u"error", 0, 
            std::vector<matlab::data::Array>({ factory.createScalar("One or three outputs required")}));
    }
}

参考

関連するトピック