Main Content

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 は別のコンパイラを選択する可能性があります。

MinGWMATLAB 用に手動設定

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" を参照してください。

MinGWLinux 上の 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 関数はオブジェクト XMyClass から作成し、次に入力引数の数をチェックします。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 が呼び出されます。関数 doErrorCheckingerror タイプの例外をスローします。しかし、この例外は MEX ファイル内ではキャッチされず、MATLAB のクラッシュを引き起こします。

この動作は、std::exception クラスから継承されたクラスに対しても発生します。

回避方法

例外を MEX 関数でキャッチします。

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    try{
        createMyClass();
    }
    catch(error e){
        // Error handling
    }
}

参考

関連するトピック