Main Content

使用 MinGW -w64 编译 C/C++ MEX 文件的限制和疑难解答

不要链接到使用非 MinGW 编译器编译的库文件

如果您使用 MinGW® 编译器编译的 MEX 文件链接到使用非 MinGW 编译器(例如 Microsoft® Visual Studio®)编译的库,该文件将不会在 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 可能会选择其他编译器。

手动为 MATLAB 配置 MinGW

从 MATLAB 附加功能菜单安装 MinGW 时,MATLAB 会自动检测 MinGW 编译器。

如果需要,您可以手动配置 MinGW;如果您有 Windows® 管理特权,可以使用 configuremingw 脚本。要下载此脚本,请参阅 MATLAB Answers 文章 "I already have MinGW on my computer.How do I configure it to work with MATLAB"

MinGW 的行为与 Linux 中的 gcc/g++ 相似

当使用 mex 命令修改编译器标识符时,请使用 Linux® 编译器标识符 CFLAGSCXXFLAGS,而不是 Windows 标识符 COMPFLAGS

C++ MEX 文件内有关使用 MEX 异常的潜在内存泄漏

使用 MinGW-w64 编译器编译的 C++ MEX 文件中的错误处理与 MATLAB 的错误处理不一致。如果 C++ MEX 文件包含某个类,则使用 mexErrMsgIdAndTxt 函数引发 MEX 异常可能导致为该类创建的对象发生内存泄漏。

MathWorks 建议您使用 C++ MEX API,而不是 C 矩阵 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 函数从 MyClass 创建了对象 X,然后检查输入参量的数量。如果该 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
    }
}

另请参阅

相关主题