Marshal MATLAB Structures (structs) in C#
Structures (or structs) are MATLAB® arrays with elements accessed by textual field designators.
Structs consist of data containers, called fields. Each field stores an array of some MATLAB data type. Every field has a unique name.
Creating a MATLAB Structure
MATLAB structures are ordered lists of name-value pairs. You represent them
in C# by defining a .NET struct or class, as long as it has
public
fields or properties corresponding to the MATLAB structure. A field or property in a .NET struct or class can have a
value convertible to and from any MATLAB data type, including a cell array or another structure. The examples
in this article use both .NET struct
s and classes.
In MATLAB, create a structure that contains name
,
score
, and grade
to store information for
a
student.
S.name = 'Ed Plum'; S.score = 83; S.grade = 'B+'
S
) with three
fields.S = name: 'Ed Plum' score: 83 grade: 'B+'
S
. The following code creates a structure array of
dimensions
(1,3)
.S(2).name = 'Tony Miller'; S(2).score = 91; S(2).grade = 'A-';
S(3).name = 'Mark Jones'; S(3).score = 85; S(3).grade = 'A-';
Using .NET Structs and Classes
You create .NET structs and classes to marshal data to and from MATLAB structures.
The .NET struct
Student
is an example of a .NET struct
that is
marshaling .NET types as inputs to MATLAB function, such as sortstudents
, using
public
fields and properties. Note the publicly declared field
name
, and the properties grade
and
score
.
In addition to using a .NET struct
, Please note the following:
Student
can also be defined as a class.Even though in this example a combination of
public
fields and properties is used, you can also use only fields or properties.
The C# class SimpleStruct
uses public
readable properties as input to MATLAB, and uses a public
constructor when marshaling as
output from MATLAB.
When this class is passed as input to a MATLAB function, it results in a MATLAB struct with fields Field1
and
Field2
, which are defined as public
readable properties. When a MATLAB struct with field names Field1
and
Field2
is passed from MATLAB, it is used as the target .NET type (string
and
double
, respectively) because it has a constructor with input
parameters Field1
and Field2
.
MATLAB function sortstudents
takes in an array of
student
structures and sorts the input array in ascending
order by student score. Each element in the struct
array
represents different information about a student
.
The C# interface StudentSorter
and method
sortstudents
is provided to show equivalent functionality in
C#.
Your .NET structs and classes must adhere to specific requirements, based on both the level of scoping (fields and properties as opposed to constructor, for example) and whether you are marshaling .NET types to or from a MATLAB structure. See Using .NET Structs and Classes for details.
The .NET interface StudentSorter
, with the method
sortstudents
, uses the previously defined .NET
Student
struct for inputs and outputs. When marshaling
structs for input and output in .NET, the Student
struct or class
must be included in the MWStructureList
attribute. For more
information about this custom attribute, see the .NET API documentation located in
.$MPS_INSTALL
/client
When you run the application, the following output is generated:
Unsorted list of students : Tony Miller : A : 90 Ed Plum : B+ : 80 Mark Jones : A- : 85 Sorted list of students : Ed Plum : B+ : 80 Mark Jones : A- : 85 Tony Miller : A : 90 Press any key to continue . . .
Using Attributes
In addition to using the techniques described in Using .NET Structs and Classes, attributes also provide versatile ways to marshal .NET types to and from MATLAB structures.
The MATLAB
Production Server™-defined attribute MWStructureList
can be scoped at
field, property, method, or interface level.
In the following example, a MATLAB function takes a cell
array (vector) as input
containing various MATLAB
struct
data types and returns a cell
array
(vector) as output containing modified versions of the input
struct
s.
Define the cell
array using two .NET struct types:
.NET struct Types Struct1 and Struct2
Without using the MWStructureList
attribute, the C# method
signature in the interface StructExample
, is as follows:
public interface StructExample { public object[] modifyinput(object[] cellArrayWithStructs); }
Note that this signature, as written, provides no information about the structure
types that cellArrayWithStructs
include at run time. By using the
MWStructureList
attribute, however, you define those types
directly in the method signature:
public interface StructExample { [MWStructureList(typeof(Struct1), typeof(Struct2))] public object[] modifyinput(object[] cellArrayWithStructs); }
The MWStructureList
attribute can be scoped at:
Method Attributes
In this example, the attribute MWStructureList
is used as a
method attribute for marshaling both the input and
output types.
public interface StructExample { [MWStructureList(typeof(Struct1), typeof(Struct2))] public object[] modifyinput(object[] cellArrayWithStructs); }
In this example, struct types Struct1
and
Struct2
are not exposed to method
modifyinputNew
because modifyinputNew
is a separate method signature
public interface StructExample { [MWStructureList(typeof(Struct1), typeof(Struct2))] public object[] modifyinput(object[] cellArrayWithStructs); public object[] modifyinputNew(object[] cellArrayWithStructs); }
Interface Attributes
When used at an interface level, an attribute is shared by all the methods of the interface.
In the following example, both modifyinput
and
modifyinputNew
methods share the interface attribute
MWStructureList
because the attribute is defined prior to
the interface
declaration.
[MWStructureList(typeof(Struct1), typeof(Struct2))] public interface StructExample { public object[] modifyinput(object[] cellArrayWithStructs); public object[] modifyinputNew(object[] cellArrayWithStructs); }
Fields and Property Attributes
Write the interface using public
fields or
public
properties.
You can represent this type of .NET struct
in three ways
using fields and properties:
At the field:
Using
public
field and theMWStructureList
attribute:public struct StructWithinStruct { [MWStructureList(typeof(Struct1), typeof(Struct2))] public object[] cellArrayWithStructs; }
At the property, for both
get
andset
methods:Using
public
properties and theMWStructureList
attribute:public struct StructWithinStruct { private object[] arr; [MWStructureList(typeof(Struct1), typeof(Struct2))] public object[] cellArrayWithStructs { get { return arr; } set { arr = value; } } }
At the property, for both or either
get
orset
methods, depending on whether this struct will be used as an input to MATLAB or an output from MATLAB:public struct StructWithinStruct { private object[] arr; public object[] cellArrayWithStructs { [MWStructureList(typeof(Struct1), typeof(Struct2))] get { return arr; } [MWStructureList(typeof(Struct1), typeof(Struct2))] set { arr = value; } } }
Note
The last two examples, which show attributes used at the property, produce the same result.