Main Content

C++ MEX ソース ファイルの作成

基本的な C++ MEX 関数を作成する方法は次のとおりです。この関数は、基本的な入出力を示すために、単純に入力配列の各要素にオフセットを追加します。MEX 関数のソース コードの作成に関する詳細な説明については、C++ MEX 関数の構造および関連トピックを参照してください。

ソース ファイルの作成

エディターを使用して、.cpp 拡張子をもつファイルを作成し、コメントとして説明を追加します。たとえば、MyMEXFunction.cpp のようになります。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

必要なヘッダー ファイルの追加

C++ MEX 関数については、次のヘッダー ファイルを追加します。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

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

便利な定義の使用

オプションで、matlab::data の名前空間を指定し、他の便利な機能を定義します。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

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

using namespace matlab::data;
using matlab::mex::ArgumentList;

MexFunction クラスの定義

すべての C++ MEX 関数は、MexFunction という名前のクラスとして実装されます。このクラスは matlab::mex::Function から派生させなければなりません。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

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

using namespace matlab::data;
using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {

};

operator() の定義

すべての MexFunction クラスは、matlab::mex::ArgumentList 型の引数を 2 つ受け入れるために、関数呼び出し演算子 operator() をオーバーライドしなければなりません。これらの引数には入力と出力が含まれます。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

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

using namespace matlab::data;
using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {
public:
    void operator()(ArgumentList outputs, ArgumentList inputs) {

    }

};

メンバー関数を追加して引数をチェック

引数の型とサイズが正しいかどうかをテストして確認します。テストが失敗した場合、MATLAB® 関数 error を呼び出します。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

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

using namespace matlab::data;
using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {
public:
    void operator()(ArgumentList outputs, ArgumentList inputs) {

    }
    void checkArguments(ArgumentList outputs, ArgumentList inputs) {
        // Get pointer to engine
        std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();

        // Get array factory
        ArrayFactory factory;

        // Check offset argument: First input must be scalar double
        if (inputs[0].getType() != ArrayType::DOUBLE ||
            inputs[0].getNumberOfElements() != 1)
        {
            matlabPtr->feval(u"error",
                0,
                std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
        }

        // Check array argument: Second input must be double array
        if (inputs[1].getType() != ArrayType::DOUBLE)
        {
            matlabPtr->feval(u"error",
                0,
                std::vector<Array>({ factory.createScalar("Input must be double array") }));
        }
        // Check number of outputs
        if (outputs.size() > 1) 
        {
            matlabPtr->feval(u"error",
                0,
                std::vector<Array>({ factory.createScalar("Only one output is returned") }));
        }
    }
};

計算の実装

スカラー オフセットを取得し、const double に代入します。入力配列を取得し、それを matlab::data::TypedArray<double> に移動して、配列を操作します。オフセットを配列の各要素に追加し、変更された配列を出力変数に代入します。

/* MyMEXFunction
 * c = MyMEXFunction(a,b);
 * Adds offset argument a to each element of double array b and
 * returns the modified array c.
*/

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

using namespace matlab::data;
using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {
public:
    void operator()(ArgumentList outputs, ArgumentList inputs) {
        checkArguments(outputs, inputs);
        const double offSet = inputs[0][0];
        TypedArray<double> doubleArray = std::move(inputs[1]);
        for (auto& elem : doubleArray) {
            elem += offSet;
        }
        outputs[0] = doubleArray;
    }

    void checkArguments(ArgumentList outputs, ArgumentList inputs) {
        // Get pointer to engine
        std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();

        // Get array factory
        ArrayFactory factory;

        // Check offset argument: First input must be scalar double
        if (inputs[0].getType() != ArrayType::DOUBLE ||
            inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||
            inputs[0].getNumberOfElements() != 1)
        {
            matlabPtr->feval(u"error",
                0,
                std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
        }

        // Check array argument: Second input must be double array
        if (inputs[1].getType() != ArrayType::DOUBLE ||
            inputs[1].getType() == ArrayType::COMPLEX_DOUBLE)
        {
            matlabPtr->feval(u"error",
                0,
                std::vector<Array>({ factory.createScalar("Input must be double array") }));
        }
        // Check number of outputs
        if (outputs.size() > 1) {
            matlabPtr->feval(u"error",
                0,
                std::vector<Array>({ factory.createScalar("Only one output is returned") }));
        }
    }
};

設定とビルド

サポートされているコンパイラをインストールしたら、mex コマンドを使用して MEX 関数をビルドします。

mex -setup c++
mex MyMEXFunction.cpp

MEX 関数のビルドの詳細については、C++ MEX プログラムのビルドを参照してください。

MEX 関数の呼び出し

MATLAB から MEX 関数を呼び出します。

b = MyMEXFunction(11.5, rand(1000));

参考

| |

関連するトピック