Вот как создать базовую функцию C++ MEX. Эта функция просто добавляет смещение к каждому элементу входного массива, чтобы продемонстрировать основные входные и выходные данные. Более подробное обсуждение создания исходного кода функции MEX см. в разделе Структура функции C++ MEX и связанные темы.
С помощью редактора создайте файл с помощью .cpp расширение и добавление комментированных инструкций. Например, MyMEXFunction.cpp.
/* MyMEXFunction * Adds second input to each * element of first input * a = MyMEXFunction(a,b); */
Для функций C++ MEX добавьте эти файлы заголовков.
/* MyMEXFunction * Adds second input to each * element of first input * a = MyMEXFunction(a,b); */ #include "mex.hpp" #include "mexAdapter.hpp"
Дополнительно укажите пространство имен для matlab::data и определить другие удобства.
/* MyMEXFunction * Adds second input to each * element of first input * a = MyMEXFunction(a,b); */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList;
Все функции C++ MEX реализованы как класс с именем MexFunction. Этот класс должен быть производным от matlab::mex::Function.
/* MyMEXFunction
* Adds second input to each
* element of first input
* a = MyMEXFunction(a,b);
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
};Все MexFunction классы должны переопределять оператор вызова функции, operator(), чтобы принять два аргумента типа matlab::mex::ArgumentList. Эти аргументы содержат входные и выходные данные.
/* MyMEXFunction
* Adds second input to each
* element of first input
* a = MyMEXFunction(a,b);
*/
#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
* Adds second input to each
* element of first input
* a = MyMEXFunction(a,b);
*/
#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 first input argument
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 second input argument
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
* Adds second input to each
* element of first input
* a = MyMEXFunction(a,b);
*/
#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 first input argument
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 second input argument
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.
b = MyMEXFunction(11.5, rand(1000));
matlab::mex::ArgumentList | matlab::mex::Function | mex