Объекты MATLAB в MEX-функциях

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-функцию.

mexgetproperty.cpp

Смотрите также

|

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте