MEX-функции могут получить доступ к свойствам объектов MATLAB® с помощью MATLAB:: механизм:: MATLABEngine:: setProperty и 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 objec 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-функция выполняет некоторые дополнительные шаги, которые могут быть полезными в вашей программе.
Проверка аргументов подтверждает правильное количество входных параметров и вызывает isa
MATLAB, чтобы определить класс входного объекта.
Поддержка или 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 an 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 a 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:: getProperty | mATLABEngine:: MATLABEngine:: setProperty