C/C++ MEX ファイルを MinGW -w64 でコンパイルする際のトラブルシューティングと制限
MinGW 以外のコンパイラでコンパイルしたライブラリ ファイルにリンクしない
MinGW® コンパイラを使用して、Microsoft® Visual Studio® など、MinGW 以外のコンパイラでコンパイルしたライブラリにリンクする MEX ファイルをビルドした場合、そのファイルは MATLAB® では実行されません。異なるコンパイラで生成されたライブラリ (.lib
) ファイルは、互いに互換性がありません。
MinGW の dlltool
ユーティリティを使用して、新しいライブラリ ファイルを生成できます。
MinGW インストール フォルダーにスペースを含めない
MinGW は、パス名にスペースを含む場所にはインストールしないでください。たとえば、次は使用しないでください。
C:\Program Files\mingw-64
代わりに次を使用してください。
C:\mingw-64
MEX コマンドが MinGW を選択しない
MinGW コンパイラのみがシステムにインストールされている場合、mex
コマンドは C および C++ MEX ファイルの両方に対し自動的に MinGW を選択します。複数の C または C++ コンパイラがある場合は、mex -setup
を使用して C および (必要に応じて) C++ MEX ファイルの両方に MinGW を選択します。
mex -setup mex -setup cpp
mex -setup
とだけ入力して MinGW を選択すると、C++ ファイルをコンパイルする際に、mex
は別のコンパイラを選択する可能性があります。
MinGW を MATLAB 用に手動設定
MinGW を MATLAB の [アドオン] メニューからインストールすると、MATLAB は MinGW コンパイラを自動検出します。
Windows® の管理者権限がある場合は、configuremingw
スクリプトを使用して、必要に応じて MinGW を手動で構成できます。このスクリプトをダウンロードする方法は、MATLAB Answers の記事 "I already have MinGW on my computer.How do I configure it to work with MATLAB" を参照してください。
MinGW が Linux 上の gcc/g++ と同様の動作を示す
mex
コマンドを使用してコンパイラ フラグを変更する場合は、Windows のフラグ COMPFLAGS
の代わりに Linux® のコンパイラ フラグ CFLAGS
または CXXFLAGS
を使用します。
MEX 例外の使用における C++ MEX ファイル内でのメモリ リークの可能性
MinGW-w64 コンパイラでコンパイルされた C++ MEX ファイルでのエラー処理は、MATLAB のエラー処理と整合性がありません。C++ MEX ファイルにクラスが含まれている場合、関数 mexErrMsgIdAndTxt
を使用して MEX の例外をスローすると、そのクラス用に作成されたオブジェクトにメモリ リークが発生する可能性があります。
MathWorks では、C 行列 API の代わりに C++ MEX API を使用することを推奨しています。詳細については、MATLAB (MEX ファイル) から呼び出せる C++ 関数の記述を参照してください。
たとえば、次の C++ MEX 関数には MyClass
クラスが含まれています。
#include "mex.h" class MyClass { public: MyClass() { mexPrintf("Constructor called"); } ~MyClass() { mexPrintf("Destructor called"); } }; void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { MyClass X; if (nrhs != 0) { mexErrMsgIdAndTxt("MATLAB:cppfeature:invalidNumInputs", "No input arguments allowed."); } }
MEX 関数はオブジェクト X
を MyClass
から作成し、次に入力引数の数をチェックします。MEX 関数が mexErrMsgIdAndTxt
を呼び出した場合、MATLAB のエラー処理ではオブジェクト X
のメモリが解放されず、したがって、メモリ リークが発生します。
C++ MEX ファイルにおける未処理の明示的例外による MATLAB の予期しない終了
C++ MEX ファイルの関数が明示的な例外をスローし、その例外が MEX ファイル内で catch
ステートメントによりキャッチされない場合は、エラーは MATLAB コマンド ラインに伝播されず、例外によって MATLAB が終了します。
#include "mex.h" class error {}; // Throw an exception of this class class MyClass { public: MyClass(){ mexPrintf("Constructor called."); } ~MyClass(){ mexPrintf("Destructor called."); } }; void doErrorChecking(const MyClass& obj) { // Do error checking throw error(); } void createMyClass() { MyClass myobj; doErrorChecking(myobj); } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { createMyClass(); }
MEX 関数は createMyClass
を呼び出し、これによってクラス MyClass
のオブジェクトが作成されて、関数 doErrorChecking
が呼び出されます。関数 doErrorChecking
は error
タイプの例外をスローします。しかし、この例外は MEX ファイル内ではキャッチされず、MATLAB のクラッシュを引き起こします。
この動作は、std::exception
クラスから継承されたクラスに対しても発生します。
回避方法
例外を MEX 関数でキャッチします。
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { try{ createMyClass(); } catch(error e){ // Error handling } }