Main Content

C++ MEX 함수의 구조

MEX 함수 설계

C++ MEX 함수는 함수 호출 연산자 operator()를 재정의하여 함수 객체 또는 함수 연산자(Functor)를 생성하는 클래스입니다. 이러한 객체는 입력값을 받고 출력값을 반환할 수 있는 MATLAB® 함수처럼 동작합니다.

헤더 파일

다음 헤더 파일을 포함합니다.

  • mex.hpp — C++ MEX API를 위한 용도로 이 파일을 포함함

  • mexAdapter.hppMexFunction 클래스 구현을 위해 이 파일을 한 번 포함함

네임스페이스

C++ MEX API는 다음 네임스페이스에 포함되어 있습니다.

  • matlab::mex — MEX 인터페이스

  • matlab::data — MATLAB Data API

  • matlab::engine — C++용 Engine API

진입점

C++ MEX 함수를 matlab::mex::Function 클래스에서 파생되는 MexFunction이라는 클래스로 정의합니다. MexFunction 클래스는 matlab::mex::Function 클래스의 가상 operator()를 재정의합니다.

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

class MexFunction : public matlab::mex::Function {
public:
    void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
        // check input arguments
        // implement function
        ...
    }
}

인수 전달

MATLAB은 각 입력 인수를 matlab::mex::ArgumentList 컨테이너의 matlab::data::Array로 전달합니다. ArgumentList 배열의 요소를 참조하여 각 입력값에 액세스합니다. 예를 들어, inputs[0]은 첫 번째 입력값이고 inputs[1]은 두 번째 입력값 등이 됩니다. inputs 변수의 요소 개수는 MEX 함수가 호출될 때 이 함수에 전달된 입력 인수의 개수와 같습니다. ArgumentList는 이터레이터를 지원하며 범위 기반 for 루프에서 사용할 수 있습니다.

출력 변수에 출력 인수를 할당합니다. 예를 들어, outputs[0]은 할당된 첫 번째 출력값이고 outputs[1]은 두 번째 출력값 등이 됩니다. outputs 변수의 요소 개수는 함수가 호출될 때 할당된 출력값의 개수와 같습니다.

다른 유형의 MATLAB 데이터 배열에 입력 인수를 할당하는 것이 유용할 때가 종종 있습니다. matlab::data::TypedArray<T> 또는 matlab::data::CharArray와 같은 특정 유형은 이터레이터 및 변환기 함수와 같은 추가 기능을 제공합니다. 입력값 유형과 일치하는 유형을 선택하십시오.

예를 들어, 다음 MEX 함수는 입력 배열을 matlab::data::TypedArray<double>에 할당합니다. 이 배열 유형은 배열의 각 요소에 2를 곱하는 데 사용되는 범위 기반 for 루프의 사용을 지원합니다. 수정된 배열은 outputs 변수로 반환됩니다.

#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) {

        // Validate arguments
        checkArguments(outputs, inputs);

        // Implement function
        TypedArray<double> doubleArray = std::move(inputs[0]);
        for (auto& elem : doubleArray) {
            elem *= 2;
        }

        // Assign outputs
        outputs[0] = doubleArray;
    }

    void checkArguments(ArgumentList outputs, ArgumentList inputs) {
        std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
        ArrayFactory factory;
        if (inputs[0].getType() != ArrayType::DOUBLE ||
            inputs[0].getType() == ArrayType::COMPLEX_DOUBLE)
        {
            matlabPtr->feval(u"error", 0, 
                std::vector<Array>({ factory.createScalar("Input must be double array") }));
        }

        if (outputs.size() > 1) {
            matlabPtr->feval(u"error", 0, 
                std::vector<Array>({ factory.createScalar("Only one output is returned") }));
        }
    }
};

MEX 함수를 빌드하고 실행합니다.

mex timesTwo.cpp
timesTwo(1:10)
ans =

     2     4     6     8    10    12    14    16    18    20

인수의 유효성 검사에 대한 자세한 내용은 Handling Inputs and Outputs 항목을 참조하십시오.

클래스 생성자 및 소멸자

MATLAB에서 MEX 함수를 호출하면 MexFunction 클래스가 인스턴스화됩니다. 예를 들어, 다음 MATLAB 명령문은 myMEXFunction.cpp 파일에 의해 정의된 MexFunction 클래스의 인스턴스를 만듭니다.

output = myMEXFunction(input);

이 인스턴스는 사용자가 MATLAB clear mex 명령을 호출할 때까지 계속 존재합니다.

클래스 생성자와 소멸자를 구현하면 MexFunction 객체를 생성할 때 특정 작업을 수행할 수 있습니다. 예를 들어, 다음 코드 조각은 생성자에서 읽을 텍스트 파일을 열고 소멸자에서 그 파일을 닫습니다.

#include "mex.hpp"
#include "mexAdapter.hpp"
#include <fstream> 

using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {
    std::ifstream inFile;

public:
    MexFunction() {
        inFile.open("someTextFile.txt");
    }

    ~MexFunction() {
         inFile.close();
    }

    void operator()(ArgumentList outputs, ArgumentList inputs) {
        ....
    }
};

예제는 Managing External Resources from MEX Functions 항목을 참조하십시오.

참고 항목

|

관련 항목