Extract MATLABArray data return from Matlab dll in c# with new DATA API for dotnet

Built a Matlab dll, a struct is returned from some calcuation of a matlab function.
In the old MWArray data API, I can access the data by extract and marshal it to MWNumericArray.
In the new DATA API for DotNet, I can get the field of the struct data but it is in the {MathWorks.MATLAB.Types.MATLABArray}, how can I extract this array data in C#.

5 Comments

Has problem for returning of an anonymous struct created as the traditional Matlab code as a.b=1;
Able to return a defined class object from Matlab to C#.
Managed to do it by custom marshalling as below:
public class TMConvertBinder : ConvertBinder
{
public TMConvertBinder(Type type, bool @explicit) : base(type, @explicit)
{
}
public Type Type { get; set; }
public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
throw new NotImplementedException();
}
}
Then use the customer defined type info:
MATLABArray changePoints = result.GetField("changePoints");
TMConvertBinder binder = new TMConvertBinder(typeof(double[,]), true);
var dataRead = changePoints.TryConvert(binder, out var data);
For the data array of other type such as Complex_double, int32 etc, use the below to get the data type information.
//reflect the MATLATArray property info of ArrayImplHandle
private static object ReflectMATLABArrayPropertyInfo(MATLABArray matlabArrayValue, string propertyName)
{
object value = null;
// Get the type of MyClass
Type type = matlabArrayValue.GetType();
// Get the internal property using reflection
FieldInfo internalClassField = type.GetField("ArrayImplHandle", BindingFlags.NonPublic | BindingFlags.Instance);
if (internalClassField != null)
{
// Get the value of the internal property
var internalClass = internalClassField.GetValue(matlabArrayValue);
Type internalType = internalClass.GetType();
PropertyInfo property = internalType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property != null)
{
value = property.GetValue(internalClass);
}
}
return value;
}
Still unable to convert an array of user defined STRUCT back by the customer marshalling.
public static object GetMatlabStructArrayObject(MATLABArray analysisResults, int index = 0)
{
TMConvertBinder bindercdb = new TMConvertBinder(typeof(MATLABStruct[]), true);
var dataReadcdb = analysisResults.TryConvert(bindercdb, out var datacdb);
if (dataReadcdb == true)
{
var tt = datacdb as MATLABStruct[];
if (tt!=null && tt.Length > index)
{
return tt[index];
}
}
return null;
}

Sign in to comment.

 Accepted Answer

To extract data out of "MathWorks.MATLAB.Types.MATLABArray", you can simply typecast it to the datatype you want. If the conversion is not possible, you will get an error. Consider the following example of a function which returns a struct containing a double, a string and a struct array:
MATLAB Script:
function outputStruct = getData()
% This function returns a MATLAB struct 'outputStruct'
% Output:
% outputStruct - Struct containing a double field, a string
% and a struct array.
outputStruct = struct();
% Use arguments block to map a MATLAB type to a C# type
% Struct arrays in MATLAB map to a MATLAB Data Array
% MATLABStruct type in C#
arguments (Output)
outputStruct (1,1) struct
end
% fields
outputStruct.a = 1;
outputStruct.b = "hello";
% construct struct array
sArray = struct();
sArray.index = 1;
sArray.value = "one";
sArray(2).index = 2;
sArray(2).value = "two";
sArray(3).index = 3;
sArray(3).value = "three";
outputStruct.structArray = sArray;
end
C# code to extract data from the "getData()" result:
try
{
string ctfPath = @"GetData.ctf";
using (dynamic matlab = MATLABRuntime.StartMATLAB(ctfPath))
{
// call function
MATLABFunctions.getData(matlab, out MATLABStruct outputStruct);
// extract data
double a = (double)outputStruct.GetField("a");
string b = (string)outputStruct.GetField("b");
dynamic s = (MATLABStruct[])outputStruct.GetField("structArray");
// print the MATLABStruct elements
Console.WriteLine((string)s[1].value);
}
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
The following documentation link has an example of how to access MATLABStruct elements:
Hope this helps!

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!