C# から MATLAB 関数を呼び出し、計算結果を Windows Forms アプリに表示するにはどうすればよいですか。

ボタン 1 つとグラフ表示領域 1 つを備えたシンプルな C# Windows Forms アプリケーションを作成したいと考えています。ボタンを押すと、アプリケーションが MATLAB Compiler SDK によって .NET アセンブリとしてコンパイルされた MATLAB 関数を呼び出し、計算結果を受け取り、その結果を C# の画面上にプロットできるようにしたいです。

 采纳的回答

このデモの目的は次の 2 点です。
1. C# から MATLAB 関数を呼び出すこと。
2. MATLAB の計算結果を C# のデスクトップアプリケーションに表示すること。
以下の手順では、小さな FFT デモ関数を使用し、これを DLL にコンパイルして Visual Studio から生成されたライブラリを参照し、返されたデータを Windows Forms の "Chart" コントロールに描画します。
MATLAB Compiler SDK を使用して MATLAB 関数を .NET アセンブリとしてパッケージ化し、そのアセンブリを Windows Forms のボタンコールバックから呼び出します。返された MATLAB 配列は "MWArray.dll" を通じて変換でき、標準的な C# のチャートコントロールに表示できます。
1. MATLAB 関数を作成する
以下のコードで "fftdemo.m" という名前の M ファイルを作成します。
function result = fftdemo
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
t = (0:L-1)*T; % Time vector
S = 0.8 + 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
t = t * 1000;
rng(0)
X = S + 2*randn(size(t));
freq = Fs/L*(0:L-1);
Y = abs(fft(X));
result.t = t;
result.X = X;
result.freq = freq;
result.Y = Y;
end
この関数は、時間領域データと FFT 結果を含む構造体を返します。このデモでは、C# アプリケーションで "t" と "X" をプロットします。
2. MATLAB で .NET アセンブリをビルドする
MATLAB で "Library Compiler" を開き、".NET Assembly" パッケージを作成します。
1. プロジェクトに "fftdemo.m" を追加します。
2. ".NET Assembly Info" を開きます。
3. クラス名を既定値から "fftdemo" に変更します。
4. プロジェクトをビルドします。
ビルドが成功すると、MATLAB はコンパイル済み DLL を含む出力フォルダーを作成します。対象のライブラリは通常、生成されたプロジェクトフォルダー配下の "output\build\fftdemo.dll" にあります。
3. Visual Studio で Windows Forms アプリケーションを作成する
Microsoft Visual Studio で、次の手順で新しいプロジェクトを作成します。
1. "Create a new project" を選択します。
2. "C#" を選択します。
3. "Windows Forms App (.NET Framework)" を選択します。
4. プロジェクト名と保存先を設定します。
既定のフォーム上に、Toolbox から次のコントロールを配置します。
1. "Button" を 1 つ
2. "Chart" を 1 つ
分かりやすくするため、コントロール名を次のように変更します。
1. "Button" -> "buttonRun"
2. "Chart" -> "chartFft"
ボタンをダブルクリックして、クリック時のコールバックを生成します。
4. ボタンのコールバック処理を記述する
前の手順で生成したコールバック関数に、MATLAB 関数 "fftdemo" から数値データを受け取るため、下記のコードを記述します。
private void button1_MouseClick(object sender, MouseEventArgs e)
{
// Create an instance
var obj = new Class1(); // Class name of the DLL built by MATLAB Compiler SDK
// Call the MATLAB function
MWArray[] result = obj.fftdemo(1); // Use (1) because there is one output
// Receive the output as a structure
MWStructArray structResult = (MWStructArray)result[0];
// Extract fields from the structure
MWNumericArray tArray = (MWNumericArray)structResult.GetField("t");
MWNumericArray XArray = (MWNumericArray)structResult.GetField("X");
MWNumericArray freqArray = (MWNumericArray)structResult.GetField("freq");
MWNumericArray YArray = (MWNumericArray)structResult.GetField("Y");
// Convert to C# arrays
double[] t = (double[])tArray.ToVector(MWArrayComponent.Real);
double[] X = (double[])XArray.ToVector(MWArrayComponent.Real);
double[] freq = (double[])freqArray.ToVector(MWArrayComponent.Real);
double[] Y = (double[])YArray.ToVector(MWArrayComponent.Real);
// Example: plot t and X after converting them to double[]
// Clear existing series before drawing again
chart1.Series.Clear();
chart1.Legends.Clear();
// Create a new series
var series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; // Line chart
// Add t and X as XY pairs
for (int i = 0; i < t.Length; i++)
{
series1.Points.AddXY(t[i], X[i]);
}
// Add the series to the chart
chart1.Series.Add(series1);
// Set axis titles if needed
chart1.ChartAreas[0].AxisX.Title = "t";
chart1.ChartAreas[0].AxisY.Title = "X";
// Clear existing series before drawing again
chart2.Series.Clear();
chart2.Legends.Clear();
chart2.ChartAreas[0].AxisX.LabelStyle.Format = "F0";
// Create a new series
var series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; // Line chart
// Add freq and Y as XY pairs
for (int i = 0; i < t.Length; i++)
{
series2.Points.AddXY(freq[i], Y[i]);
}
// Add the series to the chart
chart2.Series.Add(series2);
// Set axis titles if needed
chart2.ChartAreas[0].AxisX.Title = "freq";
chart2.ChartAreas[0].AxisY.Title = "Y";
//chart1.Dock = System.Windows.Forms.DockStyle.Fill;
//chart2.Dock = System.Windows.Forms.DockStyle.Fill;
}
5. 必要な参照を追加する
Solution Explorer で、MATLAB ランタイム配列ライブラリと、コンパイルした MATLAB アセンブリの両方への参照を追加します。
1. "References" または "Dependencies" を右クリックします。
2. "Add Reference" を選択します。
3. "MWArray.dll" を追加します。
4. コンパイル済みの "fftdemo.dll" を追加します。
R2025b の場合、"MWArray.dll" は次の場所にあります。
C:\Program Files\MATLAB\MATLAB Runtime\R2025b\toolbox\dotnetbuilder\bin\win64\v4.0\MWArray.dll
続いて、"Form1.cs" の先頭に次の "using" 文を追加します。
using MathWorks.MATLAB.NET.Arrays;
using fftdemo;
6. ボタンコールバックから MATLAB 関数を呼び出す
"Form1.cs" では、次のような実装例を使用できます。このサンプルでは、チャートを初期化し、コンパイル済み MATLAB 関数を呼び出し、返された配列を変換して、時間領域の信号をプロットします。
using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using MathWorks.MATLAB.NET.Arrays;
using fftdemo;
namespace MatlabCSharpDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitializeChart();
}
private void InitializeChart()
{
if (chartFft.ChartAreas.Count == 0)
{
chartFft.ChartAreas.Add(new ChartArea("MainArea"));
}
chartFft.Series.Clear();
var series = new Series("Signal")
{
ChartType = SeriesChartType.Line,
BorderWidth = 2
};
chartFft.Series.Add(series);
chartFft.ChartAreas[0].AxisX.Title = "Time (ms)";
chartFft.ChartAreas[0].AxisY.Title = "Amplitude";
}
private void buttonRun_Click(object sender, EventArgs e)
{
try
{
// Replace fftdemoClass with the generated class name shown in Library Compiler.
using (var matlab = new fftdemoClass())
{
MWStructArray result = (MWStructArray)matlab.fftdemo();
MWNumericArray tArray = (MWNumericArray)result["t", 1];
MWNumericArray xArray = (MWNumericArray)result["X", 1];
double[] tData = (double[])tArray.ToVector(MWArrayComponent.Real);
double[] xData = (double[])xArray.ToVector(MWArrayComponent.Real);
chartFft.Series["Signal"].Points.Clear();
for (int i = 0; i < tData.Length; i++)
{
chartFft.Series["Signal"].Points.AddXY(tData[i], xData[i]);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "MATLAB call failed");
}
}
}
}
アプリケーションを実行してボタンを押すと、コンパイル済み MATLAB ライブラリが "fftdemo" を実行し、返された信号がチャート領域に描画されます。
7. デモを実行する
Visual Studio で "Start" を選択するか、"F5" キーを押してアプリケーションを起動します。
想定される操作の流れは次のとおりです。
1. Windows Forms アプリケーションが起動します。
2. ユーザーがボタンを押します。
3. C# から MATLAB DLL が呼び出されます。
4. MATLAB が計算済み配列を返します。
5. フォーム上のチャートに信号データが表示されます。
これにより、必要な 2 つの機能を確認できます。
1. C# から MATLAB 関数を呼び出せること。
2. MATLAB の計算結果を C# GUI アプリケーションに表示できること。
8. トラブルシューティング
  • ビルドターゲットエラー
次のエラーが表示される場合、C# のビルドターゲットとコンパイル済み MATLAB DLL のアーキテクチャが一致していません。
System.TypeInitializationException: 'The type initializer for ... threw an exception.'
BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
多くの場合、C# プロジェクトがまだ "Any CPU" に設定されています。これを "x64" に変更してください。
1. Solution Explorer でプロジェクトを右クリックします。
2. "Properties" を選択します。
3. "Build" を開きます。
4. "Platform target" を "x64" に設定します。
あわせて、インストール済みの MATLAB Runtime のバージョンが、DLL をビルドしたリリースと一致していることも確認してください。
  • Windowsディスプレイのスケーリング問題Windows の表示倍率が 100% でない場合、フォームサイズがデザイン時のレイアウトと一致しないことがあります。ウィンドウサイズを安定させるには、アプリケーションマニフェストで DPI Awareness を有効にします。1. Solution Explorer でプロジェクトを右クリックします。
    2. "Add" を選択します。
    3. "New Item" を選択します。
    4. "Application Manifest File" を選択します。
    5. "app.manifest" を開きます。
    6. 次のブロックのコメントを外します。
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
    </application>
    このデモは、MATLAB Compiler SDK を使用して C# から MATLAB 関数を呼び出し、その結果をデスクトップ GUI に表示するまでの一連の手順をまとめた例です。

更多回答(0 个)

Community Treasure Hunt

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

Start Hunting!