MATLB Data API for .NETにて構造体のデータ型を送受信する方法

お疲れ様です。
MATLAB Compiler SDKを用いて、MATLAB関数をパッケージ化し、.NETアセンブリに統合したいと考えています。
その際、構造体のデータ型のやりとりを行いたいと考えています。
テストコードを作成してデータの送受信を行おうとしてみたところ失敗し、visual studio 2022側に以下のエラーが出ました。
Errorコード:CS1503 引数~は'out 構造体タグ名'から'out dynamic'へ変換することはできません。
そのため、構造体データ型のデータ送受信を行うチュートリアル等をご教授いただければと思います。

 Accepted Answer

こちらのドキュメントの末尾が参考になります。
For MATLAB types that do not have a corresponding C# type, such as struct or dictionary, the generated type is dynamic.
MATLABからのリターン値が構造体の場合は、dynamicデータ型で定義する必要があります。
また、MATLABデータAPIの場合の.NETとのデータのやり取りは扱うドキュメントは、「MATLAB 関数への .NET データ型の受け渡し」や「Use MATLAB Structures in .NET」にありますが、.NETの構造体をMATLABに直接入れることはできないため、MathWorks.MATLAB.Types.MATLABStructを使って.NET内でMATLABの構造体を定義する必要があります。
.NETからMATLABの構造体を引数に渡して関数を呼び出し、出力として構造体を受け取るC#のコード例は下記のとおりです。
Program.cs 抜粋
// % MATLABStructを使ってC#の中で構造体を作成
int[] myarr = new int[] { 1, 2, 3 };
MATLABStruct in1 = new MATLABStruct(("field1", myarr));
// % 出力として返ってくる構造体をdynamicで受け取る
dynamic out1;
MATLABFunctions.testStruct(matlab, in1, out out1);
// % 構造体のフィールド(field1)を取得
int[] fieldlValue = out1.GetField("field1");
// % 画面に出力 (1 2 3 が出力される)
Array.ForEach(fieldlValue, Console.WriteLine);
構造体を入出力にするMATLAB関数のサンプル (testStruct.m)
function out = testStruct(str)
if isstruct(str)
out = str;
end
end

3 Comments

いつも回答いただきありがとうございます。
MATLABからの出力として構造体ともう一つの変数、2つを受け取ろうとした際、MATLAB側でargumentsを用いてデータ型の指定を行うと.NET側でエラーが出現します。
こちらのエラー文より、compiler.build.dotNETAssemblyでビルドした結果、出力されたtestStruct.cs内の14行目、16行目のSystem.Numerics.Complexをdoubleに変換したところエラーが消えました。このエラーを最初から出現しないようにするにはどのようにしたら良いのでしょうか。
エラー文:
エラー CS1503 引数 5: は 'out double' から 'out System.Numerics.Complex' へ変換することはできません
Program.cs
using System;
using MathWorks.MATLAB.Runtime;
using MathWorks.MATLAB.Types;
using testStruct;
namespace testStruct_App
{
internal class Program
{
static void Main(string[] args)
{
string ctfPath = @"testStruct.ctf";
using (dynamic matlab = MATLABRuntime.StartMATLAB(ctfPath))
{
// % MATLABStructを使ってC#の中で構造体を作成
int[] myarr = new int[] { 1, 2, 3 };
// % double型の配列を作成
double[] mynum = new double[] {4};
MATLABStruct in1 = new MATLABStruct(("field1", myarr));
// % 出力として返ってくる構造体をdynamicで受け取る
dynamic out1;
// % 出力の定義
double out2;
MATLABFunctions.testStruct(matlab, in1, mynum, out out1, out out2);
// % 構造体のフィールド(field1)を取得
int[] fieldlValue = out1.GetField("field1");
// % 画面に出力 (1 2 3 が出力される)
Array.ForEach(fieldlValue, Console.WriteLine);
Console.WriteLine(out2);
}
}
}
}
testStruct.m
function [out1,out2]= testStruct(str,num)
arguments(Input)
str struct
num double
end
arguments(Output)
out1 struct
out2 (1,1)double
end
if isstruct(str)
out1 = str;
end
out2 = num;
end
testStruct.cs
using System;
using MathWorks.MATLAB.Types;
using MathWorks.MATLAB.Exceptions;
namespace testStruct{
public static partial class MATLABFunctions {
public static void testStruct(MATLABProvider _matlab, dynamic str, dynamic num){
dynamic _dynMatlab = _matlab;
_dynMatlab.testStruct(new RunOptions(nargout:0),str,num);
}
public static void testStruct(MATLABProvider _matlab, dynamic str, dynamic num, out dynamic out1){
dynamic _dynMatlab = _matlab;
out1 = (MATLABArray)_dynMatlab.testStruct(new RunOptions(nargout:1),str,num);
}
public static void testStruct(MATLABProvider _matlab, dynamic str, dynamic num, out dynamic out1, out System.Numerics.Complex out2){
dynamic _dynMatlab = _matlab;
(out1,out2) = ((MATLABArray,System.Numerics.Complex))_dynMatlab.testStruct(new RunOptions(nargout:2),str,num);
}
}
}
argumentsに実数の{mustBeReal}を指定することで、自動生成されるstrongly_typed_interfaceフォルダー内のtestStruct.csがSystem.Numerics.Complexからdoubleになります。サイズを指定しないとdynamicになってしまうため、(1,1)などで配列を指定しておく必要があります。
testStruct.m
function [out1,out2]= testStruct(str,num)
arguments(Input)
str struct
num (1,1) double {mustBeReal}
end
arguments(Output)
out1 struct
out2 (1,1) double {mustBeReal}
end
if isstruct(str)
out1 = str;
end
out2 = num;
end
啓嗣
啓嗣 on 11 Jan 2024
無事解決できました。早急な回答ありがとうございました。

Sign in to comment.

More Answers (0)

Products

Release

R2023b

Asked:

on 5 Jan 2024

Commented:

on 11 Jan 2024

Community Treasure Hunt

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

Start Hunting!