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