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 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:: | mATLABEngine:: MATLABEngine::