MEX-функции могут получить доступ к свойствам объектов MATLAB® с помощью MATLAB:: механизм:: MATLABEngine:: и MATLAB:: механизм:: MATLABEngine:: функции членства getProperty. Объекты, переданные MEX-функциям, ведут себя как объекты, переданные любой функции MATLAB:
Обработайте объекты - Изменения, внесенные, чтобы обработать объекты в MEX-функциях, влияют на объект в рабочей области вызывающей стороны.
Объекты значения - Изменения, внесенные, чтобы оценить объекты в MEX-функциях, влияют только на независимую копию объекта в рабочей области MEX-функции.
Поэтому объекты значения, измененные в MEX-функциях, должны быть возвращены в вызывающую сторону, тогда как объекты указателя не должны быть возвращены. Для получения дополнительной информации о поведении объекта смотрите Объектную Модификацию.
Чтобы получить значение свойства, сделайте разделяемую копию объекта как matlab::data::Array
. Например, принятие объекта является первым входным параметром, присвойте его переменной:
matlab::data::Array object(inputs[0]);
Создайте массив данных MATLAB правильного типа для значения свойства. Например, принимая свойство под названием Name
содержит вектор символов MATLAB, задайте новое значение как matlab::data::CharArray
. Используйте matlab::data::ArrayFactory
создать массив.
matlab::data::CharArray propName = matlabPtr->getProperty(object, u"Name");
Если вход к MEX-функции является объектным массивом, вызовите getProperty
с индексом объекта в массиве, значение свойства которого вы хотите получить. Например, этот фрагмент кода возвращает значение Name
свойство для четвертого элемента в объектном массиве, objectArray
.
matlab::data::Array objectArray(inputs[0]); matlab::data::CharArray propName = matlabPtr->getProperty(objectArray, 3, u"Name");
Чтобы установить значение свойства, сделайте разделяемую копию объекта как matlab::data::Array
. Например, принятие объекта является первым входным параметром, присвойте его переменной.
matlab::data::Array object(inputs[0]);
Создайте массив данных MATLAB правильного типа для значения свойства. Например, принимая свойство под названием Name
содержит вектор символов MATLAB, задайте новое значение как matlab::data::CharArray
. Используйте matlab::data::ArrayFactory
создать массив.
Вызовите движок MATLAB setProperty
функция с matlabPtr
разделяемый указатель.
matlabPtr->setProperty(object, u"Name", factory.createCharArray("New value for Name"));
Если вход к MEX-функции является объектным массивом, вызовите setProperty
с индексом объекта в массиве, значение свойства которого вы хотите установить. Например, этот фрагмент кода устанавливает значение Name
свойство для четвертого элемента в объектном массиве, objectArray
.
matlab::data::Array objectArray(inputs[0]); matlabPtr->setProperty(objectArray, 3, u"Name", factory.createCharArray("New value for Name"));
Когда MEX-функция изменяет свойство объекта путем присвоения значения свойству, значение свойства больше не совместно используется с объектом в рабочей области вызывающей стороны. Данные в свойствах, которые не изменяются, остаются разделяемыми. Таким образом, поведение копирования при записи влияет на модифицированное свойство, не целый объект.
Этот пример использует EmployeeID
класс, чтобы создать объект. Этот класс задает два свойства. Name
свойство задано как 1-any массив числа элементов типа char
. Picture
свойство задано как 1000 800 массив элемента типа uint8
для изображения сотрудника.
classdef EmployeeID properties Name (1,:) char Picture (1000,800) uint8 end methods function obj = EmployeeID(n,p) if nargin > 0 obj.Name = n; obj.Picture = p; end end end end
Следующая MEX-функция изменяет изображение, содержавшееся в объекте EmployeeID
класс, чтобы уменьшить интенсивность самых ярких значений в изображении. MEX-функция выполняет эти шаги:
Перемещает входной параметр в matlab::data::Array
использование std::move
.
Использование matlab::engine::MATLABEngine::getProperty
получить значение свойства изменить.
Задает переменную как тип, подходящий для значения свойства. Используйте matlab::data::TypedArray<uint8_t>
потому что типом MATLAB является uint8
.
Повторно присвойте модифицированный массив свойству объекта с помощью matlab::engine::MATLABEngine::setProperty
.
Возвращает модифицированный объект как MEX-функцию выход.
#include "mex.hpp" #include "mexAdapter.hpp" using matlab::mex::ArgumentList; using namespace matlab::data; class MexFunction : public matlab::mex::Function { std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine(); public: void operator()(ArgumentList outputs, ArgumentList inputs) { // Move object to variable Array obj = std::move(inputs[0]); // Get property value and modify TypedArray<uint8_t> imageData = matlabPtr->getProperty(obj, u"Picture"); for (auto& elem : imageData) { if (elem > 240) { elem = elem - elem/100; } } // Set property value and assign to output matlabPtr->setProperty(obj, u"Picture", imageData); outputs[0] = obj; } };
После сохранения этого кода в файле (названный reduceGlare.cpp
в этом примере), скомпилируйте его с mex
функция. Вызовите эту MEX-функцию из MATLAB с EmployeeID
возразите, как введено.
EmployeeObject = EmployeeID('My Name',randi([1 255],1000,800,'uint8')); EmployeeObject = reduceGlare(EmployeeObject);
Этот пример создает MEX-функцию, которая принимает EmployeeID
возразите и новое значение для его Name
свойство как его входные параметры. После установки свойства к новому значению функция возвращает модифицированный объект. Эта MEX-функция выполняет некоторые дополнительные шаги, которые могут быть полезными в вашей программе.
Проверка аргументов подтверждает правильное количество входных параметров и вызывает MATLAB isa
определить класс входного объекта.
Поддержка любого char
или string
введите для значения, чтобы установить Name
свойство.
Сравнение текущего значения свойства, чтобы определить, должно ли обновление быть сделано.
Чтобы видеть исходный код, нажмите modifyObjectProperty.cpp
и EmployeeID.m
открыть файлы в редакторе MATLAB. Используйте mex
команда, чтобы создать MEX-функцию.
Чтобы запустить этот пример, добавьте modifyObjectProperty.cpp
файл и EmployeeID.m
класс к папке на вашем пути MATLAB. После выполнения mex
установите, выполните эти операторы:
mex modifyObjectProperty.cpp EmployeeObject = EmployeeID('My Name',randi([1 255],1000,800,'uint8')); EmployeeObject = modifyObjectProperty(EmployeeObject,'New Name');
Вот MexFunction::operator()
реализация.
include "mex.hpp" #include "mexAdapter.hpp" using matlab::mex::ArgumentList; using namespace matlab::data; class MexFunction : public matlab::mex::Function { public: void operator()(ArgumentList outputs, ArgumentList inputs) { // Check for correct inputs checkArguments(outputs, inputs); // Assign the input object to a matlab::data::Array Array object(inputs[0]); // Member function to set properyt value assignProperty(object, inputs); // Return modified object outputs[0] = object; }
MexFunction::checkArguments
функция выполняет эти проверки:
MEX-функция должна быть вызвана двумя аргументами.
Первый аргумент должен быть объектом EmployeeID
класс.
void checkArguments(ArgumentList out, ArgumentList in) { std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine(); ArrayFactory factory; // Check number of inputs if (in.size() != 2) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Two inputs required") })); } // Use isa function to test for correct class std::vector<Array> args{ in[0], factory.createCharArray("EmployeeID") }; TypedArray<bool> result = matlabPtr->feval(u"isa", args); if (result[0] != true) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Input must be EmployeeID object") })); } }
MexFunction::assignProperty
функция определяет, передается ли новое значение для свойства в как char
MATLAB вектор или как
string
и присваивает вход, заданный как matlab::data::CharArray
или matlab::data::StringArray
соответственно.
Прежде, чем присвоить новое значение Name
свойство, эта функция сравнивает текущее значение, чтобы определить, отличается ли это и старается не делать присвоение, если это не.
void assignProperty(Array& obj, ArgumentList in) { std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine(); ArrayFactory factory; std::string newPropertyValue; // Determine if input is MATLAB char or MATLAB string if (in[1].getType() == ArrayType::CHAR) { CharArray newName(in[1]); newPropertyValue = newName.toAscii(); } else if (in[1].getType() == ArrayType::MATLAB_STRING) { StringArray newName(in[1]); newPropertyValue = (std::string)newName[0]; } else { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Name must be char or string") })); } // If new value is different from new value, set new value CharArray currentName = matlabPtr->getProperty(obj, u"Name"); if (currentName.toAscii() != newPropertyValue) { matlabPtr->setProperty(obj, u"Name", factory.createCharArray(newPropertyValue)); } }
Для примера, который использует объект указателя, загрузите следующий файл и следуйте инструкциям в файле, чтобы создать и запустить MEX-функцию.
mATLABEngine:: MATLABEngine:: | mATLABEngine:: MATLABEngine::