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
}
}