Main Content

C++ MEX 関数のアウトプロセスでの実行

MATLAB® は C++ MEX 関数を別のプロセスで実行できます。C++ MEX 関数を別のプロセスで実行することで、以下が可能になります。

  • C++ MEX 関数でのクラッシュから MATLAB プロセスを分離する。

  • MATLAB と互換性のない C++ MEX 関数でサードパーティ ライブラリを使用する。

  • 複数の C++ MEX 関数を単一のプロセスで実行することでメモリを節約する。

  • C++ デバッガーを MEX ホスト プロセスに接続する。

  • Ctrl + C を使用して C++ MEX 関数の実行を中断する。

メモ

C++ 関数をアウトプロセスで呼び出す際に C++ と MATLAB の間で受け渡しされる変数のサイズは、2 GB に制限されています。この制限は、プロセス間で渡されるデータとサポート情報に適用されます。

アウトプロセスでの実行方法

C++ MEX 関数をアウトプロセスで実行するには、次の手順に従います。

  1. C++ MEX 関数を記述し、C++ MEX プログラムのビルドの手順を使用してビルドします。イン プロセスおよびアウトプロセスでの実行用に作成された関数間で必要なコードの変更はありません。

  2. 関数 mexhost を使用して MEX ホスト プロセスを作成します。

  3. mexhost によって返される matlab.mex.MexHost オブジェクトの feval メソッドを使用して、C++ MEX 関数をホスト プロセスで実行します。

アウトプロセスでの実行時、C++ MEX 関数は常に MATLAB の現在のフォルダーと同じフォルダーで実行されます。MEX ホスト オブジェクトの作成後に MATLAB の現在のフォルダーを変更すると、C++ MEX 関数コンテキストでも同じ変更が行われます。

MEX 関数 arrayProduct をアウトプロセスで実行

次の例では、C++ MEX 関数 arrayProduct をアウトプロセスで実行します。C++ MEX のソース コードはファイル arrayProduct.cpp で利用可能です。この C++ MEX 関数例を使用するには、arrayProduct.cpp ソース ファイルを開いて、それを MATLAB パスに保存し、C++ MEX プログラムのビルドの手順を使用して C++ MEX 関数をビルドします。

C++ MEX 関数をビルドしたら、関数 mexhost を使用して MEX ホスト プロセスを開始します。この関数は、matlab.mex.MexHost クラスのオブジェクトを返します。

feval メソッドを使用して、C++ MEX 関数 arrayProduct をホスト プロセスで実行します。C++ MEX 関数の名前と引数を feval に渡します。feval の出力を割り当てることで、結果を MATLAB に返します。

mh = mexhost;
result = feval(mh,'arrayProduct',2,[1 2 3 4])
result =
     2     4     6     8

関数 arrayProduct を別の MEX ホスト プロセスで実行します。まず、関数 mexhost を再度呼び出して出力を別の変数に割り当てることで、MEX ホスト プロセスを作成します。次に、新しいホストで feval を呼び出します。

mh2 = mexhost;
result2 = feval(mh2,'arrayProduct',2,rand(1,10));

mexhost によって返される同じ matlab.mex.MexHost オブジェクトを使用して、別の C++ MEX 関数を同じプロセスで実行できます。

result2 = feval(mh2,'anotherMexFunction',inputs);

プロセスのライフ サイクル

MEX ホスト プロセスのライフ サイクルは、mexhost によって返される matlab.mex.MexHost オブジェクトのライフ サイクルと結合しています。ハンドル オブジェクトと同様に、オブジェクトがどこからも参照されなくなると、MATLAB は delete メソッドを呼び出します。MATLAB が delete を呼び出した場合、またはユーザーがオブジェクトに対して delete を明示的に呼び出した場合、MATLAB は MexHost オブジェクトに関連付けられているプロセスを終了します。

次のいずれかのオプションを指定して関数 clear を呼び出すことで、プロセスを明示的に終了できます。

  • 関数 mexhost によって返される変数を clear する

  • clear classesclear java または clear all

C++ MEX 関数のリビルド

mex コマンドは、C++ MEX 関数をビルド前に自動的にアンロードします。したがって、ユーザーが C++ MEX 関数を MEX ホスト プロセスから明示的にアンロードする必要はありません。

clear mex または clear functions を呼び出すことで、MEX ホスト プロセスからすべての C++ MEX 関数を明示的にアンロードすることができます。関数名に対して clear を呼び出すことで、特定の C++ MEX 関数をアンロードします。

C++ MEX 関数のアンロードを回避するには、関数 mexLock を使用します。C++ MEX 関数をロック解除するには、関数 mexUnlock を使用します。これらの関数は、ホスト プロセスの C++ MEX 関数に対してフラグを設定または設定解除して、C++ MEX 関数のアンロードを制御します。

MEX ホスト プロセスに関する情報の取得

MEX ホスト プロセスに関する情報を取得するには、matlab.mex.MexHost オブジェクトを使用します。次のプロパティはプロセスとロードされた関数に関する情報を提供します。

  • EnvironmentVariables には、プロセス用に設定された環境変数の名前と値が含まれている。

  • Functions には、MEX ホスト プロセスに読み込まれたすべての C++ MEX 関数の名前が含まれている。

  • ProcessName には、MEX ホスト プロセスの名前 (既定では MATLABMexHost) が含まれている。

  • ProcessIdentifier には、プロセス識別子が含まれている。

これらのプロパティの詳細については、matlab.mex.MexHost を参照してください。

常にアウトプロセスで実行

場合によっては、C++ MEX 関数を常にアウトプロセスで実行する必要があります。たとえば、MATLAB と C++ MEX 関数の間でサードパーティ ライブラリの競合が存在する場合、アウトプロセスで実行する必要があります。

C++ MEX 関数をアウトプロセスで実行する便利な方法を提供するには、ラッパー MATLAB 関数を作成します。ラッパー関数は MEX ホスト オブジェクトを作成し、そのプロセスで C++ MEX 関数を実行します。

たとえば、ドキュメンテーションに例として含まれている C++ MEX 関数 arrayProduct.cpp 用にラッパー関数を作成するものと仮定します。arrayProduct.m という名前をもつ MATLAB 関数を作成し、このファイルを MATLAB パス上にあるフォルダーに配置します。C++ MEX 関数をビルドし、コンパイルされた MEX ファイルに別の名前を割り当てます。

ラッパー関数によって作成された matlab.mex.MexHost オブジェクトは永続変数に割り当てられるため、後続のラッパー関数の呼び出し間でプロセスが破棄されることはありません。関数はこのオブジェクトを使用して、C++ MEX 関数のアウトプロセス実行用に feval メソッドを呼び出します。MEX ホスト オブジェクトが有効でない場合は、関数によって MEX ホスト プロセスが作成されます。

function result = arrayProduct(scalefactor,inputarray)
    persistent mh
    if ~(isa(mh,'matlab.mex.MexHost') && isvalid(mh))
        mh = mexhost;
    end
    result = feval(mh,"arrayProductMEX",scalefactor,inputarray);
end

C++ MEX 関数をビルドするには、arrayProduct.cpp ソース ファイルを開き、それを MATLAB パスに保存します。このトピックC++ MEX プログラムのビルドの手順を使用して、C++ MEX 関数をビルドします。

次のコマンドは、ルート名 arrayProductMEX を使用して MEX ファイルをビルドし、ラッパー関数を使用してそのファイルをフォルダーに配置します。この例では、フォルダーは MyPathFolder であると想定しています。フォルダーが存在しない場合、mex コマンドによって作成されます。

mex -output arrayProductMEX -outdir MyPathFolder arrayProduct.cpp

C++ MEX 関数を使用するには、ほかの関数のようにラッパー関数を介してコマンド ラインから呼び出します。

result = arrayProduct(2,[1 2 3 4]);
result
result =

     2     4     6     8

次のコードは C++ MEX 関数を for ループ内で呼び出します。関数 arrayProduct の最初の呼び出しによって MEX ホスト プロセスが作成されます。たとえば C++ MEX 関数のクラッシュなどでプロセスが破棄されていない限り、後続の呼び出しでも同じプロセスが使用されます。

for k = 1:5
   results(k,:) = arrayProduct(k,[1 2 3 4]);
end
results
results =
     1     2     3     4
     2     4     6     8
     3     6     9    12
     4     8    12    16
     5    10    15    20

MEX ホスト プロセスを破棄するには、MEX ホスト プロセスの変数 (この例では mh) を永続変数として定義しているすべての関数をクリアします。この例では、関数 arrayProduct.m をクリアします。

clear arrayProduct.m

clear functions を呼び出すと、永続変数に保存されている matlab.mex.MexHost オブジェクトが破棄されるため、MEX ホスト プロセスが終了します。

アウトプロセスでの MEX 関数のデバッグ

C++ デバッガーを C++ MEX 関数に接続して、ブレーク ポイントを設定することで、プログラムをデバッグできます。C++ MEX 関数を設定してアウトプロセスでデバッグする手順は次の通りです。

  • -g オプションを指定して mex コマンドを使用することで C++ MEX ソース コードをビルドし、デバッグ シンボルをインクルードする。

  • 関数 mexhost を使用してホスト プロセスを作成する。この関数は matlab.mex.MexHost のオブジェクトを返します。

  • matlab.mex.MexHost オブジェクトの ProcessIdentifier プロパティからプロセス識別子を取得する。

  • プロセス識別子を使用して、C++ デバッガーをプロセスに接続する。

  • ブレークポイントをソース コードに挿入する。

  • feval メソッドを使用して C++ MEX 関数をアウトプロセスで実行する。

特定のデバッガーの使用に関する詳細については、それらのデバッガーのドキュメンテーションを参照してください。

Microsoft Visual Studio を使用したデバッグ

  1. C++ コンパイラとして Visual Studio® が選択されていることを確認します。この例では、Microsoft® Visual Studio 2015 を使用します。

    cpp = mex.getCompilerConfigurations('C++','Selected');
    cpp.Name
    ans =
    
        'Microsoft Visual C++ 2015'
  2. -g オプションを指定して mex コマンドを使用することで C++ MEX ソース コードをビルドします。この例では、myMexFunction.cpp という名前の C++ MEX ソース ファイルがあると仮定します。

    mex -g myMexFunction.cpp
  3. MEX ホスト プロセスを作成し、MexHost オブジェクトを返します。

    mh = mexhost;
  4. Visual Studio を起動します。MATLAB セッションは終了しないでください。

  5. Visual Studio の [デバッグ] メニューで [プロセスにアタッチ] を選択します。

    [プロセスにアタッチ] ダイアログ ボックスで MATLABMexHost プロセスを選択し、[アタッチ] をクリックします。

  6. Visual Studio はデータを読み込んだ後、空白のコード ペインを表示します。

  7. [ファイル][開く][ファイル] をクリックしてファイルを選択することで、C++ MEX ソース ファイルを開きます。

  8. 目的のコード行を右クリックし、コンテキスト メニューから [ブレークポイント][ブレークポイントの挿入] をクリックしてブレークポイントを設定します。

  9. MATLAB で matlab.mex.MexHostfeval メソッドを使用して、C++ MEX 関数をアウトプロセスで実行します。

    result = feval(mh,'myMexFunction',input1,input2,...)
  10. デバッガーが提供する機能を使用して、ソース コードをデバッグします。

Linux システムでのデバッグ

Linux® システムでは、GNU® gdb デバッガーなどのデバッガーを使用できます。次の手順に従って gdb デバッガーを使用します。

  1. -g オプションを指定して mex コマンドを使用することで C++ MEX ソース コードをビルドします。この例では、myMexFunction.cpp という名前の C++ MEX ソース ファイルがあると仮定します。

    mex -g myMexFunction.cpp
  2. MEX ホスト プロセスを作成し、MexHost オブジェクトを返します。

    mh = mexhost;
  3. MexHost オブジェクトの ProcessIdentifier プロパティからプロセス識別子を取得します。戻り値は MEX ホスト プロセスの識別子を表す string です。以下に例を示します。

    mh.ProcessIdentifier
    ans = 
    
        "13892"

    プロセス識別子は作成されるプロセスごとに異なります。

  4. Linux ターミナルから、MEX ホスト プロセスにデバッガーを接続します。たとえば、GNU gdb デバッガーを使用して、MATLAB の MEX ホスト オブジェクトから取得した C++ MEX ファイル名とプロセス識別子を指定して gdb を呼び出します。

    gdb myMexFunction -pid=13892
  5. C++ MEX 関数にブレーク ポイントを設定します。たとえば、gdb を使用して、myMexFunction.cpp の 21 行目にブレーク ポイントを設定します。

    break myMexFunction.cpp:21
  6. MATLAB から matlab.mex.MexHostfeval メソッドを使用して、C++ MEX 関数をアウトプロセスで実行します。

    result = feval(mh,'myMexFunction',input1,input2,...)

    MATLAB はデバッガーからの応答を待機します。

  7. Linux ターミナルから、デバッガーが提供する機能を使用してソース コードをデバッグします。

Macintosh システムでのデバッグ

Macintosh システムでは、LLDB デバッガーを使用します。

  1. -g オプションを指定して mex コマンドを使用することで C++ MEX ソース コードをビルドします。この例では、myMexFunction.cpp という名前の C++ MEX ソース ファイルがあると仮定します。

    mex -g myMexFunction.cpp
  2. MEX ホスト プロセスを作成し、MexHost オブジェクトを返します。

    mh = mexhost;
  3. MexHost オブジェクトの ProcessIdentifier プロパティからプロセス識別子を取得します。戻り値は MEX ホスト プロセスの識別子を表す string です。

    mh.ProcessIdentifier
    ans = 
    
        "13892"

    プロセス識別子は作成されるプロセスごとに異なります。

  4. macOS ターミナルから、MEX ホスト プロセスにデバッガーを接続します。MATLAB の MEX ホスト オブジェクトから取得した MEX ホスト プロセス識別子を指定して lldb を呼び出します。たとえば、プロセス識別子が 13892 であると仮定して、このプロセスに LLDB デバッガーを接続します。

    lldb -p 13892
  5. ソース コード内にブレーク ポイントを設定します。たとえば、次のコマンドは myMexFunction.cpp の行番号 21 にブレーク ポイントを設定します。

    breakpoint set -f myMexFunction.cpp -l 21
  6. MATLAB から matlab.mex.MexHostfeval メソッドを使用して、C++ MEX 関数をアウトプロセスで実行します。

    result = feval(mh'myMexFunction',input1,input2,...)

    MATLAB はデバッガーからの応答を待機します。

  7. macOS ターミナルから C または continue入力します。プログラムの実行がブレークポイントで停止します。

  8. macOS ターミナルから、デバッガーが提供する機能を使用してソース コードをデバッグします。

参考

|

関連するトピック