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 関数をアウトプロセスで実行するには、次の手順に従います。
C++ MEX 関数を記述し、C++ MEX プログラムのビルドの手順を使用してビルドします。イン プロセスおよびアウトプロセスでの実行用に作成された関数間で必要なコードの変更はありません。
関数
mexhost
を使用して MEX ホスト プロセスを作成します。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
classes
、clear
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 を使用したデバッグ
C++ コンパイラとして Visual Studio® が選択されていることを確認します。この例では、Microsoft® Visual Studio 2015 を使用します。
cpp = mex.getCompilerConfigurations('C++','Selected'); cpp.Name
ans = 'Microsoft Visual C++ 2015'
-g
オプションを指定してmex
コマンドを使用することで C++ MEX ソース コードをビルドします。この例では、myMexFunction.cpp
という名前の C++ MEX ソース ファイルがあると仮定します。mex -g myMexFunction.cpp
MEX ホスト プロセスを作成し、
MexHost
オブジェクトを返します。mh = mexhost;
Visual Studio を起動します。MATLAB セッションは終了しないでください。
Visual Studio の [デバッグ] メニューで [プロセスにアタッチ] を選択します。
[プロセスにアタッチ] ダイアログ ボックスで
MATLABMexHost
プロセスを選択し、[アタッチ] をクリックします。Visual Studio はデータを読み込んだ後、空白のコード ペインを表示します。
[ファイル] 、 [開く] 、 [ファイル] をクリックしてファイルを選択することで、C++ MEX ソース ファイルを開きます。
目的のコード行を右クリックし、コンテキスト メニューから [ブレークポイント] 、 [ブレークポイントの挿入] をクリックしてブレークポイントを設定します。
MATLAB で
matlab.mex.MexHost
のfeval
メソッドを使用して、C++ MEX 関数をアウトプロセスで実行します。result = feval(mh,'myMexFunction',input1,input2,...)
デバッガーが提供する機能を使用して、ソース コードをデバッグします。
Linux システムでのデバッグ
Linux® システムでは、GNU® gdb
デバッガーなどのデバッガーを使用できます。次の手順に従って gdb
デバッガーを使用します。
-g
オプションを指定してmex
コマンドを使用することで C++ MEX ソース コードをビルドします。この例では、myMexFunction.cpp
という名前の C++ MEX ソース ファイルがあると仮定します。mex -g myMexFunction.cpp
MEX ホスト プロセスを作成し、
MexHost
オブジェクトを返します。mh = mexhost;
MexHost
オブジェクトのProcessIdentifier
プロパティからプロセス識別子を取得します。戻り値は MEX ホスト プロセスの識別子を表す string です。以下に例を示します。mh.ProcessIdentifier
ans = "13892"
プロセス識別子は作成されるプロセスごとに異なります。
Linux ターミナルから、MEX ホスト プロセスにデバッガーを接続します。たとえば、GNU
gdb
デバッガーを使用して、MATLAB の MEX ホスト オブジェクトから取得した C++ MEX ファイル名とプロセス識別子を指定してgdb
を呼び出します。gdb myMexFunction -pid=13892
C++ MEX 関数にブレーク ポイントを設定します。たとえば、
gdb
を使用して、myMexFunction.cpp
の 21 行目にブレーク ポイントを設定します。break myMexFunction.cpp:21
MATLAB から
matlab.mex.MexHost
のfeval
メソッドを使用して、C++ MEX 関数をアウトプロセスで実行します。result = feval(mh,'myMexFunction',input1,input2,...)
MATLAB はデバッガーからの応答を待機します。
Linux ターミナルから、デバッガーが提供する機能を使用してソース コードをデバッグします。
Macintosh システムでのデバッグ
Macintosh システムでは、LLDB デバッガーを使用します。
-g
オプションを指定してmex
コマンドを使用することで C++ MEX ソース コードをビルドします。この例では、myMexFunction.cpp
という名前の C++ MEX ソース ファイルがあると仮定します。mex -g myMexFunction.cpp
MEX ホスト プロセスを作成し、
MexHost
オブジェクトを返します。mh = mexhost;
MexHost
オブジェクトのProcessIdentifier
プロパティからプロセス識別子を取得します。戻り値は MEX ホスト プロセスの識別子を表す string です。mh.ProcessIdentifier
ans = "13892"
プロセス識別子は作成されるプロセスごとに異なります。
macOS ターミナルから、MEX ホスト プロセスにデバッガーを接続します。MATLAB の MEX ホスト オブジェクトから取得した MEX ホスト プロセス識別子を指定して
lldb
を呼び出します。たとえば、プロセス識別子が13892
であると仮定して、このプロセスに LLDB デバッガーを接続します。lldb -p 13892
ソース コード内にブレーク ポイントを設定します。たとえば、次のコマンドは
myMexFunction.cpp
の行番号 21 にブレーク ポイントを設定します。breakpoint set -f myMexFunction.cpp -l 21
MATLAB から
matlab.mex.MexHost
のfeval
メソッドを使用して、C++ MEX 関数をアウトプロセスで実行します。result = feval(mh'myMexFunction',input1,input2,...)
MATLAB はデバッガーからの応答を待機します。
macOS ターミナルから
C
またはcontinue
を入力します。プログラムの実行がブレークポイントで停止します。macOS ターミナルから、デバッガーが提供する機能を使用してソース コードをデバッグします。