简介这份支持包面向希望利用编译型语言提升MATLAB计算性能的科研与工程人员适用于MATLAB 2023B/2024A环境。它集成了MinGW-w64编译器可调用GCC工具链在Windows平台编译C、C和Fortran代码并通过MEX接口将原生程序嵌入MATLAB同时为TrueTime 2.0提供编译器支撑方便用户在Simulink中建立实时操作系统模型仿真和验证嵌入式系统的实时行为。压缩包共2000个文件主体为Python脚本、C/C头文件及说明文档896个py脚本多用于工具链配置和自动化处理787个h与243个hpp头文件负责支撑原生代码与MATLAB的互操作另有txt说明、Shell脚本及少量C源码辅助安装、链接与调试。包体大小133.84MB目录包含include、lib、bin、etc、share等标准模块并附有x86_64-w64-mingw32架构文件与licenses许可无需额外配置即可解压部署。已有1912人学习下载适合需要加速数值计算、扩展MEX功能或开展实时仿真研究的MATLAB中高级用户。1. 编译器装不上时MATLAB 才真正变成一个黑匣子我第一次被 MinGW 卡住是在帮某实验室复现一个图像处理 Demo 时。代码是 C 写的算法逻辑跑在 MATLAB 里一等函数都写好了却在mex -setup这一步报“找不到支持的编译器”——那感觉就像 MATLAB 突然变成了黑匣子你明明装了支持包系统里也有 gcc它偏不认。你正在看的这个标题“MATLAB Support for MinGW-w64 C/C/Fortran Compiler”说的就是那个官方支持包它负责把 MinGW-w64 这套开源编译器接进 MATLAB 的 MEX 编译体系和 Simulink 代码生成链路。这篇文章会把安装、配置、编译命令和坑一条条讲透让新手能照着走通第一步让熟手能少踩几个我已经替你踩过的坑。2. 为什么 MATLAB 自己不内置编译器MinGW-w64 在编译链里的位置2.1 MATLAB 需要外部编译器的三个场景MATLAB 本身是一个解释型环境但下面三件事必须有外部 C/C 编译器第一编译 MEX 文件也就是用 C/C 写算法核心、在 MATLAB 里直接调用这是性能敏感型任务最常见的落地方式。第二Simulink 生成代码无论是嵌入式代码还是桌面级 S-FunctionSimulink Coder 都要把模型编译成可执行文件或静态库。第三通过loadlibrary调用外部 DLL当你手上只有 C 接口的动态库时MATLAB 需要一套编译器配套的 SDK 头文件和链接器来生成接口定义。这三个场景里编译器不是可选项是硬依赖。没有编译器你的 MATLAB 就只能做一个计算器加绘图工具算法落地寸步难行。2.2 MinGW-w64 是什么它和 GCC、TDM-GCC 什么关系MinGW-w64 是 GCC 在 Windows 下的移植发行版提供gcc、g、gfortran三套前端编译产物是 Windows 原生可执行的二进制不依赖额外的 POSIX 模拟层。这是它和 Cygwin 最大的区别MinGW 生成的程序直接在 Windows 的进程模型下运行加载 msvcrt.dll 或 ucrtbase.dll而不是模拟 Linux 运行时。你可能会在论坛里看到 TDM-GCC 这个名字它也是 MinGW-w64 的一个发行分支。区别在打包方式TDM-GCC 做的是一键集成包自带工具链协调版本而 MATLAB 官方支持包自带的是与 MATLAB 版本匹配的 MinGW-w64 分支。我建议你优先用支持包自带的版本因为它经过 MATLAB 内部测试配置注册表项齐全手动装 TDM-GCC 再手动配置容易在版本检查上翻车。2.3 支持包其实做了三件事安装支持包之后系统里并不只是多了一个编译器它实际完成了三个动作第一释放一套完整的 MinGW-w64 工具链到 MATLAB 的 SupportPackages 目录下包括gcc、g、gfortran和mingw32-make。第二在 MATLAB 的编译器注册表里登记这条路径mex -setup才能枚举到它。第三安装匹配的头文件和链接配置让mex知道去哪里找mex.h、libmx.lib、libmex.lib这些 MEX 编译必需的 SDK 文件。这也是为什么网上有些教程让你自己下 MinGW 然后改系统 PATH最后mex -setup还是找不到——因为缺了第二步的注册信息。装支持包这个动作本质上是往 MATLAB 的编译器候选列表里插入一个合法选项。2.4 为什么不用 MSVCMSVC 是 Visual Studio 自带的编译器如果你的 Windows 上有完整 VS 安装MATLAB 也会自动识别它。但 MSVC 和 MinGW 是两套不同的 ABIC 层面尤其明显MSVC 用的 STL 实现和 MinGW 用的 libstdc 二进制不兼容用 MSVC 编译的第三方 C 库不能直接喂给 MinGW 链接器反之亦然。MinGW-w64 的优势是免费、无许可证负担、装完即用对个人开发者尤其友好。后文所有命令默认走 MinGW-w64如果你必须用 MSVC编译选项和库路径逻辑大同小异只是链接器报错风格完全不同。3. 安装支持包从 Add-On 安装到 mex -setup 验证3.1 在 Add-On Explorer 里搜 minGW装完先别急着编译打开 MATLAB 主界面右上角菜单里找“附加功能”点进去之后选择“获取附加功能”搜索框里输入MinGW就能看到MATLAB Support for MinGW-w64 C/C/Fortran Compiler这个条目点安装即可。安装器会自动检查你的 MATLAB 版本然后拉取匹配的编译器分支整个安装过程可能持续几分钟取决于网络状况。这一步有个关键注意事项安装完成之后先重启 MATLAB再执行后面的验证步骤。这不是玄学是支持包的注册机制在起作用——安装器把编译器信息写进了 MATLAB 启动时才扫描的配置位置当前会话里不会重新读取。我见过太多人装完就马上敲mex -setup然后报错到论坛问一圈才发现只是没重启这个失误属于完全可以避免的踩坑。3.2 验证编译器是否被识别mex.getCompilerConfigurations重启 MATLAB 之后先跑一条命令确认编译器已经被登记 mex.getCompilerConfigurations(C, Installed) ans 编译器配置: 名称: MinGW-w64 C/C Compiler 版本: 8.1 路径: C:\ProgramData\MATLAB\SupportPackages\R20xx\3P.instrset\mingw_w64.instrset\mingw64这条命令是只读查询不会修改任何配置。返回结果里重点看两个字段版本号和路径。路径应该指向 SupportPackages 目录下的mingw_w64.instrset\mingw64分支而不是系统里的其他 MinGW 安装目录。如果这里能列出编译器说明支持包注册成功下一步才轮到mex -setup。mex.getCompilerConfigurations和mex.getCompilerConfigurations(C, Installed)的区别在于前者返回 MATLAB 可直接调用的所有编译器包括 C 和 C后者明确限定语言和安装状态。查 Fortran 编译器时把参数换成Fortran即可但新版 MATLAB 对 Fortran MEX 的官方支持已经很弱这条我们放到第 4 章专门说。3.3 mex -setup 切换默认编译器并编一个最小样例验证确认编译器出现在列表里之后在 MATLAB 命令行执行 mex -setup C MEX 配置为使用 MinGW-w64 C/C Compiler 以编译 C 语言代码。 要选择不同的语言请从以下选项中选择一个命令: mex -setup C mex -setup Fortran如果机器上同时还装了 MSVCmex -setup会列出候选列表让你选序号。选择 MinGW 之后MATLAB 会把默认编译器持久化到用户的配置文件里之后每次 MATLAB 启动都默认指向它。mex -setup C只影响 C 语言不会覆盖 C 语言的默认配置同理mex -setup C只改 C。配置完成之后我习惯先编一个最小 MEX 文件验证整个链路是通的。新建文件check_mex.c#include mex.h void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *in, *out; mwSize n; if (nrhs 1) { mexErrMsgIdAndTxt(check_mex:nrhs, 至少需要 1 个输入); } n mxGetNumberOfElements(prhs[0]); plhs[0] mxCreateDoubleMatrix(1, n, mxREAL); in mxGetPr(prhs[0]); out mxGetPr(plhs[0]); for (mwSize i 0; i n; i) { out[i] in[i] * 2.0 1.0; } }在命令行执行编译 mex -O check_mex.c check_mex([1 2 3 4]) ans 3 5 7 9能输出这个结果说明编译器、SDK、链接器、运行时整条链路都是通的。-O是启用编译器优化对发布用途的 MEX 文件基本是标配。mexFunction的参数顺序是固定的nlhs是输出数量plhs是输出数组指针nrhs是输入数量prhs是输入数组指针——写任何 MEX 文件都必须按这个签名来入口函数名不能改改了就链接失败。4. 用支持包编译 C/C/Fortran 代码命令、参数和边界4.1 C 代码编译从普通函数到 mexFunction 的改造逻辑C 语言的 MEX 文件改造思路很简单你已有的 C 函数负责计算mexFunction负责跟 MATLAB 交换数据。还是以check_mex.c为例它的核心计算只有一行out[i] in[i] * 2.0 1.0但在 MATLAB 看来它就是一个合法的内置函数支持任意长度的 double 向量输入。实际工程里更常见的做法是把你的算法封装在一个普通函数里然后在mexFunction里调用它。比如#include mex.h static double my_algorithm(double x) { return x * x 3.0 * x - 1.0; } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double val, out; if (nrhs ! 1) { mexErrMsgIdAndTxt(calc_mex:nrhs, 需要一个标量输入); } val mxGetScalar(prhs[0]); out my_algorithm(val); plhs[0] mxCreateDoubleScalar(out); }编译命令不变mex -O calc_mex.c。mxGetScalar返回第一个输入元素的值要求输入是标量或者单元素矩阵mxCreateDoubleScalar创建 1×1 的 double 输出。这两个函数处理的是 MATLAB 的mxArray结构跟原生 C 类型之间的转换由 API 自己完成你不需要关心内存细节但也不要自己free由 MATLAB 分配的内存。4.2 C 代码编译标准库和 STL 怎么用MinGW-w64 在 MATLAB 里编译 C最大的便利是可以直接用std::vector、std::string、std::map这些标准库组件不用担心内存管理。下面这段代码演示了如何把一个 MATLAB 向量搬进std::vector做累加后返回标量#include mex.h #include vector #include numeric void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs ! 1) { mexErrMsgIdAndTxt(sum_mex:nrhs, 需要一个输入向量); } const double *in mxGetPr(prhs[0]); mwSize n mxGetNumberOfElements(prhs[0]); std::vectordouble v(in, in n); double total std::accumulate(v.begin(), v.end(), 0.0); plhs[0] mxCreateDoubleScalar(total); }编译时注意一点在 MATLAB 命令行里直接敲mex -stdc17 sum_mex.cpp是不生效的因为mex命令本身不直接解析-std。需要通过环境变量把参数透传给底层编译器 mex CXXFLAGS$CXXFLAGS -stdc17 sum_mex.cpp这条命令的意思是在 m ex 默认的 C 编译参数基础上追加-stdc17。$CXXFLAGS是 MATLAB 在调用底层编译器时预设的默认参数集合你必须保留它然后追加你的额外要求。同理如果要加优化等级可以在命令行加-O它会映射到底层的-O2不需要手动指定优化级别。用 C 写 MEX 还有个值得养成的习惯凡是涉及 C 标准库的头文件比如math.h、string.h在 C 代码里尽量改用cmath、cstring然后用std::限定。这不只是风格问题某些平台上 C 头文件和 C 头文件的符号导出方式不同混用可能导致链接阶段出现undefined reference。4.3 Fortran 编译的边界官方支持收窄后的替代路线标题里带 Fortran确实有历史原因。老版本的 MATLAB 支持直接用mex编译.f或.f90文件mex -setup Fortran曾经是一个合法选项。但在较新的版本里MATLAB 对 Fortran MEX 的官方支持已明显收窄很多版本连mex -setup Fortran都列不出来即使你在系统里装好了 gfortran 也认不到。现状是支持包内含gfortran编译器它在 MATLAB 生态里的主要价值转向了两个方向——一是 Simulink 的 S-Function Builder在某些硬件支持包里Fortran 生成的 S-Function 仍需 gfortran 参与编译二是通过loadlibrary调用你自己用 Fortran 写的 DLL。第二种是目前更可靠的落地方式gfortran -shared -fPIC -o mylib.dll mylib.f90在 MATLAB 里用loadlibrary加载并调用loadlibrary(mylib.dll, mylib.h); result calllib(mylib, myfunc, 3.14); unloadlibrary(mylib);这条路线的关键坑在于mylib.h必须声明 Fortran 函数的 C 接口否则calllib不知道该用什么签名去调。常见做法是在 Fortran 代码里用bind(C)属性导出标准接口或者提供一个薄薄的 C 包装函数内部再转发给 Fortran 子程序。如果你确实需要在新版 MATLAB 里编译传统的 Fortran MEX 文件只能降级到某个老版本 MATLAB或者改用旧式 Gateway 例程这里面隐藏的兼容性成本很高非必要不建议投入。5. 避坑支持包装了却用不上多半是这几个原因5.1 现象Add-On 显示已安装mex -setup 仍然找不到编译器原因支持包安装器虽然完成了文件释放但注册信息是写入 MATLAB 启动时扫描的持久化位置你当前这个 MATLAB 会话不会自动重读。这也是为什么我第 3 章反复强调装完先重启。解决彻底退出 MATLAB不是关掉图窗是命令行进程完全结束重新启动后再执行mex -setup C。如果重启之后还是找不到检查支持包是否真的装在了当前 MATLAB 版本对应的 SupportPackages 目录下有时候你装了 R2021a 的支持包却拿 R2023b 的 MATLAB 去跑自然识别不到。5.2 现象机器上同时装了 MSVC 和 MinGWmex 选了 MinGW 却链接失败原因如果你用 MSVC 编译过第三方库产物的.lib文件格式与 MinGW 的lib完全不同。MinGW 的g链接器只能识别 GCC 风格的静态库和导入库直接把 MSVC 的.lib传给 MinGW典型报错是undefined reference to __imp_xxx或者干脆找不到符号。解决第三方库必须用 MinGW 版本重新编译。如果库本身是开源的用支持包里的mingw32-make重新构建如果库只提供了 MSVC 编译的预编译二进制那你只有两条路——换用 MSVC 作为 MATLAB 默认编译器或者找该库的 MinGW 版本预编译包。混用 ABI 基本无解别在这个问题上浪费时间。5.3 现象mex 编译过程报“编译器版本不匹配”或“该 MATLAB 版本不支持当前编译器”原因系统 PATH 里的 gcc 版本与支持包安装的版本冲突或者你手动安装了系统级 MinGW 覆盖了支持包注册的路径。MATLAB 在调用编译器时会做版本检查版本过低或过高都会直接拒绝。解决不要自己装系统级 MinGW 再手动配 PATH让支持包安装器全权管理。如果已经装了系统级 MinGW检查系统 PATH 里是否包含了它的bin目录把它从 PATH 的前部挪到后面或者干脆删除让 MATLAB 优先找到支持包内的编译器。检查方式在 MATLAB 里跑mex.getCompilerConfigurations(C, Installed)看显示的路径是不是 SupportPackages 下的那个。5.4 现象编译成功运行时提示缺少 libgcc_s_seh-1.dll 或 libstdc-6.dll原因MinGW-w64 编译出的 MEX 文件启动时需要加载两个运行时 DLL——libgcc_s_seh-1.dll和libstdc-6.dll。这两个文件在支持包的mingw64\bin目录下但该目录不在系统 PATH 里Windows 加载 DLL 时找不到。解决把支持包的bin目录加到系统 PATH。路径大概是C:\ProgramData\MATLAB\SupportPackages\R20xx\3P.instrset\mingw_w64.instrset\mingw64\binR20xx 换成你的 MATLAB 版本。改完 PATH 后要重启 MATLAB 才生效。如果不想动系统 PATH也可以在启动脚本里设置环境变量在userpath下的startup.m里写setenv(PATH, [C:\...\mingw64\bin; getenv(PATH)])效果一样只是只对 MATLAB 进程生效不污染系统全局变量。5.5 现象C 代码编译遇到 undefined reference 到 std::string 或 std::vector 相关符号原因代码里用了 C 标准库但链接阶段没拉入 libstdc。MinGW-w64 的 g 前端正常情况下会自动链接标准库但如果你用mex的-c选项手动编译成.o、再手动链接就很容易漏掉-lstdc这一步。解决大部分情况下不用-c直接让mex一条命令完成“编译 链接”。如果确实需要手动分步链接命令里显式加-lstdc。另外检查你的 C 源文件后缀.c后缀会让编译器按 C 语言处理链接时自然找不到 C 符号。把文件重命名为.cpp一切都会正常。6. 进阶用法把编译流程固定成脚本让验证不再靠手感熟练之后每次手动敲mex -setup和mex命令其实是浪费。我把自己的标准流程固定成了一个编译脚本放在项目根目录每次拿到新机器只需要跑一遍% compile_all.m if isempty(mex.getCompilerConfigurations(C, Installed)) error(MinGW-w64 编译器未安装请先安装 MATLAB Support for MinGW-w64); end mex -O CXXFLAGS$CXXFLAGS -stdc17 sum_mex.cpp mex -O calc_mex.c % 自动验证 assert(abs(sum_mex(1:10) - 55) 1e-12, sum_mex 计算结果异常); assert(abs(calc_mex(2) - 9) 1e-12, calc_mex 计算结果异常); disp(全部编译和验证通过);这个脚本的核心逻辑是先检查编译器状态再编译最后用断言做数值验证不让任何一步靠手感。第一个assert验证累加函数的结果第二个验证二次函数代入x2时46-19的结果。任何一步失败脚本立刻抛出错误而不是等你在 MATLAB 里手动试函数再慢慢找问题。另一个实用技巧是增量编译你只改了一个源文件时用mex -c file.cpp生成.o文件然后链接时直接复用这个.o可以节省大量重复编译时间。配合支持包自带的g手动编译能做的事比想象中大。最后分享一个习惯我现在拿到任何新环境第一件事永远是先跑mex.getCompilerConfigurations(C, Installed)确认编译器状态正常再去碰项目代码。这个习惯帮我避免了一半以上的环境类报错希望你也能用上。希望帮到你。本文还有配套的精品资源点击获取