使用 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® 编译器标识符 CFLAGS
或 CXXFLAGS
,而不是 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 } }