ドキュメンテーション センター

  • 評価版
  • 製品アップデート

目次

MATLAB の .NET デリゲート

.NET デリゲート

.NET Framework では、delegate はメソッド シグネチャを定義する型です。これにより関数をパラメーターとして渡すことができます。デリゲートを使用すると、.NET アプリケーションで MATLAB® コールバック関数またはクラス インスタンス メソッドの呼び出しを行うことができます。MATLAB がコールバック関数またはクラス メソッドのシグネチャを定義する際の規則については、「.NET オブジェクトの使用」の「メソッド シグネチャの読み取り」を参照してください。デリゲートおよびその使用時の詳細は、Microsoft® Developer Network などの外部リソースを参照してください。

デリゲートの使用に向けては 3 つの手順があります。

  • 宣言 — .NET アプリケーションには宣言が含まれています。デリゲートを MATLAB 言語で宣言することはできません。

  • インスタンス化 — MATLAB では、デリゲートのインスタンスを作成し、特定の MATLAB 関数または .NET オブジェクト メソッドに関連付けます。

  • 呼び出し - 指定された入力引数および出力引数と共に関数を呼び出します。関数名の代わりにデリゲート名を使用します。

MATLAB での .NET デリゲートの呼び出し

この例は、MATLAB でデリゲートを使用する方法を示しています。MATLAB 関数 (char) を使用してデリゲートを作成します。他の例については、「.NET オブジェクト メソッドからのデリゲートの作成」を参照してください。

この例は、以下のタスクで構成されています。

C# アセンブリでのデリゲートの宣言

C# の例 NetDocDelegate.csmatlabroot/extern/examples/NET/NetSample フォルダーにあり、以下の例で使用するデリゲートを定義します。コードを表示するには、MATLAB エディターでファイルを開きますファイルを開きます。この例を実行するには、「MATLAB 例での .NET アプリケーションの構築」の説明のとおりに NetDocDelegate アセンブリをビルドします。

MATLAB へのデリゲートを含むアセンブリの読み込み

NetDocDelegate アセンブリが c:\work フォルダーにある場合、以下のコマンドでファイルを読み込みます。

dllPath = fullfile('c:','work','NetDocDelegate.dll');
NET.addAssembly(dllPath);

MATLAB 関数の選択

delInteger デリゲートは、整数の入力で文字列を返す任意のメソッドをカプセル化します。MATLAB 関数 char は、非負の整数の文字配列 (文字列) への変換を実行しますが、これは delInteger デリゲートと一致するシグネチャをもちます。たとえば、以下のコマンドは ! 文字を表示します。

char(33)

MATLAB におけるデリゲートのインスタンスの作成

delInteger デリゲートのインスタンスを作成するには、関数 char の関数ハンドルを渡します。

myFunction = NetDocDelegate.delInteger(@char);

MATLAB におけるデリゲート インスタンスの呼び出し

関数 char の場合と同じように myFunction を使用します。たとえば、以下のコマンドは ! 文字を表示します。

myFunction(33)

.NET オブジェクト メソッドからのデリゲートの作成

以下の C# クラスは、delInteger デリゲートに一致するシグネチャをもつメソッド AddEggs および AddFlour を定義します。

 C# Recipe ソース ファイル

Recipe アセンブリをビルドした後、コールバックとして AddEggs を使用してこれを読み込み、デリゲート myFunc を作成します。

NET.addAssembly(dllPath);
NET.addAssembly('c:\work\Recipe.dll');
obj = Recipe.MyClass;
myFunc = NetDocDelegate.delInteger(@obj.AddEggs);
myFunc(2)
ans = 
Add 2 eggs

.NET メソッドにバインドされたデリゲート インスタンスの作成

以下のように定義された C# デリゲートの場合、

namespace MyNamespace
{
  public delegate void MyDelegate();
}

MATLAB は以下のコンストラクター シグネチャを作成します。

戻り値の型名前引数
MyNamespace.MyDelegate objMyDelegate(target,
string methodName)

引数 target は、以下のいずれかです。

  • インスタンス メソッドへのバインド時の呼び出し対象オブジェクトのインスタンス

  • 静的メソッドへのバインド時の .NET 完全修飾クラス名をもつ文字列

methodName はコールバック メソッド名を指定する文字列です。

例 — .NET オブジェクト インスタンス メソッドに関連付けられたデリゲート インスタンスの作成

次の C# デリゲートおよびクラス定義の場合、

namespace MyNamespace
{
  public delegate void MyDelegate();

  public class MyClass
  {
    public void MyMethod(){}
  }
}

MATLAB でデリゲートをインスタンス化するには、以下を入力します。

targetObj = MyNamespace.MyClass();
delegateObj = MyNamespace.MyDelegate(targetObj, 'MyMethod');

例 — 静的 .NET メソッドに関連付けられたデリゲート インスタンスの作成

次の C# デリゲートおよびクラス定義の場合、

namespace MyNamespace
{
  public delegate void MyDelegate();

  public class MyClass
  {
    public static void MyStaticMethod(){}
  }
}

MATLAB でデリゲートをインスタンス化するには、以下を入力します。

delegateObj=MyNamespace.MyDelegate(...
  'MyNamespace.MyClass','MyStaticMethod');

out および ref 型の引数をもつデリゲートの呼び出し

デリゲートの out 型と ref 型をマッピングする MATLAB のルールは、メソッドのルールと同じです。「C# メソッド アクセス修飾子」を参照してください。

たとえば、以下の C# ステートメントは ref 引数をもつデリゲートを宣言します。

public delegate void delref(ref Double refArg);

対応する MATLAB デリゲート関数のシグネチャは、refArg を RHS と LHS の両方の引数としてマップします。

function refArg = myFunc(refArg)

以下の C# ステートメントは out 引数をもつデリゲートを宣言します。

public delegate void delout(
    Single argIn,  
    out Single argOut);

対応する MATLAB デリゲート関数のシグネチャは、argOut を LHS の引数としてマップします。

function argOut = myFunc(argIn)

.NET デリゲートの組み合わせと削除

MATLAB はインスタンス メソッド Combine を提供しており、これはいくつかのデリゲートを組み合わせて単一のデリゲートにします。Remove および RemoveAll メソッドは個々のデリゲートを削除します。詳細は、「.NET Framework の詳細」の説明にあるように .NET Framework クラス ライブラリを参照してください。

たとえば、NetDocDelegate.delInteger デリゲートで使用する以下の MATLAB 関数を作成します。

function out = action1(n)
out = 'Add flour';
disp(out);
end

function out = action2(n)
out = 'Add eggs';
disp(out);
end

デリゲート step1 および step2 を作成します。

step1 = NetDocDelegate.delInteger(@action1);
step2 = NetDocDelegate.delInteger(@action2);

新しいデリゲート mixItems として結合させるには、以下を入力します。

mixItems = step1.Combine(step2);

または以下を入力します。

mixItems = step1.Combine(@action2);

mixItems を呼び出します。

result = mixItems(1);

この場合、関数 action1 の後に action2 が続きます。

Add flour
Add eggs

result の値は最終デリゲート (step2) からの出力です。

result = 
Add eggs

System.Delegate クラスの静的メソッド CombineRemove、および RemoveAll も使用可能です。

mixItems から step1 を削除するには、以下を入力します。

step3 = mixItems.Remove(step1);

.NET メソッドの非同期呼び出し

MATLAB では、同期メソッドを非同期で呼び出せます。Microsoft の BeginInvoke および EndInvoke メソッドを少し変更して使用できます。詳細は、http://msdn.microsoft で MSDN® の記事「同期メソッドの非同期呼び出し」を参照してください。

デリゲートを使用すると、BeginInvoke および EndInvoke メソッドを使用して同期メソッドを非同期で呼び出すことができます。非同期呼び出しの開始スレッドが、結果処理のスレッドである必要がない場合は、呼び出しの完了時にコールバック メソッドを実行できます。コールバック メソッドの使用についての詳細は、「非同期呼び出し終了時のコールバックを使用したメソッドの非同期呼び出し」を参照してください。

    メモ:   MATLAB はシングルスレッド アプリケーションです。したがって、MATLAB 環境における非同期呼び出し処理はデッドロックとなる可能性があります。

非同期呼び出し終了時のコールバックを使用したメソッドの非同期呼び出し

非同期呼び出しが完了したら、コールバック メソッドを実行できます。コールバック メソッドは、非同期呼び出しの結果を処理するスレッドとは別のスレッドで実行されます。

手順の概要は以下のとおりです。コールバック関数を使用しない場合は、「コールバックを使用しないメソッドの非同期呼び出し」の手順に従ってください。

  • 非同期で実行する MATLAB 関数を選択または作成します。

  • C# デリゲートを選択または作成し、MATLAB 関数に関連付けます。

  • System.AsyncCallback Delegate デリゲート シグネチャを含む MATLAB コールバック関数を作成します。MSDN Web サイトで示されているシグネチャは以下のとおりです。

    public delegate void AsyncCallback(IAsyncResult ar)
    
  1. MATLAB コードを使用して、BeginInvoke メソッドを使用する非同期呼び出しを開始します。コールバック デリゲートを指定し、必要に応じてオブジェクト パラメーターも指定します。

  2. MATLAB でコマンドの実行を続けます。

  3. 非同期の関数の完了後、MATLAB はコールバック関数を呼び出します。この関数は EndInvoke メソッドを実行し、結果を取得します。

コールバックの例-  この例では、非同期で実行する以下の MATLAB 関数を作成します。

function X = DivideFunction(A, B)
if B ~= 0
    X = A / B;
else
    errid = 'MyID:DivideFunction:DivisionByZero';
    error(errid, 'Division by 0 not allowed.');
end
end

以下の MATLAB 関数を作成します。この関数は非同期メソッドの呼び出しが完了するとコールバックとして実行されます。この関数は EndInvoke メソッドの result 値を表示します。

function myCallback(asyncRes)
result = asyncRes.AsyncDelegate.EndInvoke(asyncRes);
disp(result);
end

NetDocDelegate アセンブリで定義された del2Integer デリゲートを使用します。

public delegate Int32 del2Integer(Int32 arg1, Int32 arg2);

例を実行します。

% Create the delegate
divDel = NetDocDelegate.del2Integer(@DivideFunction);
A=10;
B=5;
% Initiate the asynchronous call.
asyncRes = divDel.BeginInvoke(A,B,@myCallback,[]);

MATLAB が結果を表示します。 2

コールバックを使用しないメソッドの非同期呼び出し

手順の概要は以下のとおりです。コールバック関数を使用する場合は、「非同期呼び出し終了時のコールバックを使用したメソッドの非同期呼び出し」の手順に従ってください。

  • 非同期で実行する MATLAB 関数を選択または作成します。

  • C# デリゲートを選択または作成し、MATLAB 関数に関連付けます。

  1. MATLAB で、BeginInvoke メソッドを使用して非同期の呼び出しを開始します。

  2. MATLAB でコマンドの実行を続けます。

  3. MATLAB 関数 pause を使用して非同期の呼び出し完了をポーリングします。

  4. 非同期の関数の完了後、EndInvoke メソッドを呼び出し、結果を取得します。

コールバックを使用しない例-  この例では、MATLAB 関数 myFunction を作成します。

% MATLAB function to execute asynchrounously
function res = myFunction(strValue)
res = strValue;
end

NetDocDelegate アセンブリで定義された delString デリゲートを使用します。

public delegate string delString(string message);

MATLAB で、デリゲート myDelegate を作成し、入力値を定義して、非同期呼び出しを開始します。

myDelegate = NetDocDelegate.delString(@myFunction);
A='Hello';
asyncRes = myDelegate.BeginInvoke(A,[],[]);

BeginInvoke メソッドはオブジェクト asyncRes を返します。このオブジェクトは、非同期呼び出しの進捗状況の監視に使用します。MATLAB 関数 pause を使用して MATLAB にイベントを処理させて、結果をポーリングします。

while asyncRes.IsCompleted ~= true
    pause(0.01);
end

非同期呼び出しの結果を取得して表示します。

result = myDelegate.EndInvoke(asyncRes);
disp(result)
Hello

out および ref 型の引数をもつ EndInvoke の使用

関数 EndInvoke の MATLAB デリゲート シグネチャは、デリゲートが out または ref 型の引数をもつ場合、特別なマッピング ルールに従います。マッピングの詳細は、「out および ref 型の引数をもつデリゲートの呼び出し」を参照してください。例については、関数 EndInvoke のリファレンス ページを参照してください。

ポーリングを使用した非同期呼び出し終了時の検出

MATLAB では、メイン スレッド上でデリゲートのコールバックを実行するイベントを処理するために、MATLAB 関数 pause (または類似の関数) を呼び出さなければなりません。

.NET デリゲートのサポートの制限

MATLAB では、デリゲート インスタンスの一般的な .NET メソッドへの関連付けはサポートされていません。

メソッドを非同期で呼び出す場合は、「コールバックを使用しないメソッドの非同期呼び出し」で説明されている手法を使用します。次のことに注意してください。

  • MATLAB はシングルスレッド アプリケーションです。したがって、MATLAB 環境で非同期呼び出しを処理すると、デッドロックが発生する可能性があります。

  • MSDN のトピック で説明されている手法に関しては、MATLAB では引数をもたない WaitOne() メソッドのオーバーロードの使用はサポートされていません。

  • EndInvoke を呼び出して非同期呼び出しが完了するまで待機させることはできません。

この情報は役に立ちましたか?