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

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

mexgetproperty.cpp

См. также

|

Похожие темы