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 structs 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:
Studentcan also be defined as a class.Even though in this example a combination of
publicfields 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
structs.
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
publicfield and theMWStructureListattribute:public struct StructWithinStruct { [MWStructureList(typeof(Struct1), typeof(Struct2))] public object[] cellArrayWithStructs; }At the property, for both
getandsetmethods:Using
publicproperties and theMWStructureListattribute: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
getorsetmethods, 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.