MATLAB Objects in MEX Functions
MEX functions can access MATLAB® object properties using the setProperty and getProperty member functions. Objects passed to MEX functions behave like objects passed to any MATLAB function:
Handle objects - Changes made to handle objects in MEX functions affect the object in the caller's workspace.
Value objects - Changes made to value objects in MEX functions affect only the independent copy of the object in the workspace of the MEX function.
Therefore, value objects modified in MEX functions must be returned to the caller, whereas handle objects do not need to be returned. For more information on object behavior, see Object Modification.
Get Property Value
To get a property value, make a shared copy of the object as a
matlab::data::Array
. For example, assuming the object is the
first input argument, assign it to a variable:
matlab::data::Array object(inputs[0]);
Create a MATLAB data array of the correct type for the property value. For example,
assuming a property called Name
contains a MATLAB character vector, define the new value as a matlab::data::CharArray
. Use the matlab::data::ArrayFactory
to create
the array.
matlab::data::CharArray propName = matlabPtr->getProperty(object, u"Name");
Get Property Value from Object Array
If the input to the MEX function is an object array, call
getProperty
with index of the object in the array whose
property value you want to get. For example, this code snippet returns the value of
the Name
property for the fourth element in the object array,
objectArray
.
matlab::data::Array objectArray(inputs[0]);
matlab::data::CharArray propName = matlabPtr->getProperty(objectArray, 3, u"Name");
Set Property Value
To set a property value, make a shared copy of the object as a
matlab::data::Array
. For example, assuming the object is the
first input argument, assign it to a variable.
matlab::data::Array object(inputs[0]);
Create a MATLAB data array of the correct type for the property value. For example,
assuming a property called Name
contains a MATLAB character vector, define the new value as a matlab::data::CharArray
. Use the matlab::data::ArrayFactory
to create
the array.
Call the MATLAB engine setProperty
function with the
matlabPtr
shared pointer.
matlabPtr->setProperty(object, u"Name",
factory.createCharArray("New value for Name"));
Set Property Value in Object Array
If the input to the MEX function is an object array, call
setProperty
with index of the object in the array whose
property value you want to set. For example, this code snippet sets the value of the
Name
property for the fourth element in the object array,
objectArray
.
matlab::data::Array objectArray(inputs[0]);
matlabPtr->setProperty(objectArray, 3, u"Name",
factory.createCharArray("New value for Name"));
Object Property Copy-On-Write Behavior
When a MEX function modifies an object property by assigning a value to the property, the property value is no longer shared with the object in the caller's workspace. The data in properties that are not modified remain shared. That is, copy-on-write behavior affects the modified property, not the entire object.
Modify Property and Return Object
This example uses the EmployeeID
class to create an object.
This class defines two properties. The Name
property is defined
as a 1-by-any number of elements array of type char
. The
Picture
property is defined as a 1000-by-800 element array of
type uint8
for the employee image.
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
The following MEX function modifies the image contained in an object of the
EmployeeID
class to reduce the intensity of the brightest
values in the image. The MEX function performs these steps:
Moves the input argument to a
matlab::data::Array
usingstd::move
.Uses getProperty to get the value of the property to modify.
Defines the variable as a type appropriate for the property value. Use
matlab::data::TypedArray<uint8_t>
because the MATLAB type isuint8
.Reassign the modified array to the object property using setProperty.
Returns the modified object as the MEX function output.
#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;
}
};
After saving this code in a file (called reduceGlare.cpp
in
this example), compile it with the mex
function. Call this MEX
function from MATLAB with an EmployeeID
object as input.
EmployeeObject = EmployeeID('My Name',randi([1 255],1000,800,'uint8')); EmployeeObject = reduceGlare(EmployeeObject);
Only Modified Property Causes Copy
This example creates a MEX function that accepts a EmployeeID
object and a new value for its Name
property as its inputs. After
setting the property to the new value, the function returns the modified object.
This MEX function performs some additional steps that can be useful in your
program.
Argument checking confirms the correct number of inputs and calls the MATLAB
isa
to determine the class of the input object.Support for either
char
orstring
input for value to setName
property.Comparison of current property value to determine if the update needs to be made.
To see the source code, click modifyObjectProperty.cpp
and EmployeeID.m
to open the files in the MATLAB Editor. Use the mex
command to build the MEX
function.
To run this example, add the modifyObjectProperty.cpp
file and
the EmployeeID.m
class to a folder on your MATLAB path. After performing the mex
setup, execute these
statements:
mex modifyObjectProperty.cpp EmployeeObject = EmployeeID('My Name',randi([1 255],1000,800,'uint8')); EmployeeObject = modifyObjectProperty(EmployeeObject,'New Name');
Here is the MexFunction::operator()
implementation.
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
function performs these
checks:
The MEX function must be called with two arguments.
The first argument must be an object of the
EmployeeID
class.
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
function determines if the new
value for the property is passed in as a MATLAB
char
vector or as a string
and assigns the input defined as a
matlab::data::CharArray
or a
matlab::data::StringArray
respectively.
Before assigning the new value to the Name
property, this
function compares the current value to determine if it is different and avoids
making an assignment if it is not.
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));
}
}
Handle Objects
For an example that uses a handle object, download the following file and follow the instructions in the file to build and run the MEX function.