Функции MEX могут обращаться к свойствам объекта MATLAB ® с помощью функций-членов matlab:: engine:: MATLABEngine:: setProperty и matlab:: engine:: 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 на любое число элементов типа 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 setup, выполните следующие инструкции:
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 функция определяет, передано ли новое значение свойства как MATLAB char вектор или как 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.
matlab:: engine:: MATLABEngine:: getProperty | matlab:: двигатель:: MATLABEngine:: setProperty