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
класс, чтобы создать объект. Этот класс задает два свойства. The Name
свойство определяется как 1 на любое количество элементов массива типа char
. The 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; }
The 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") })); } }
The 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:: engine:: MATLABEngine:: setProperty