简介:MATLAB R2017a 作为广泛应用的科学计算与建模环境,在图像处理、控制系统设计等场景中常需调用外部编译器。该版本对 Visual Studio 2017 的支持补丁,面向需要借助 MEX 接口在 MATLAB 中编译 C/C++ 程序的科研与工程开发人员,用于解决 R2017a 无法识别 VS2017 编译器路径、链接选项不匹配等兼容问题。补丁包为 zip 压缩形式,共 4 个文件,以 txt 和 xml 配置为主,压缩后仅 11KB;txt 多用于记录许可、版本变化或安装时的错误报告,xml 用于写入 MATLAB 识别 VS2017 所需的编译器配置。目前已有 439 人学习。应用补丁后,用户可在 MATLAB R2017a 中正常配置并调用 VS2017 编译器,减少 MEX 编译失败与警告,避免因工具链不一致导致的中断,进而在调用 C/C++ 高效计算模块时获得接近原生的执行性能。安装后通过创建并编译简单 MEX 文件,即可验证补丁是否生效;对不熟悉 MATLAB 与 Visual Studio 混合编译环境的用户,补丁附带的记录文件也有助于快速排查安装或环境变量问题,是一份小而实用的组合工具。
1. 这个补丁是什么:别让 R2017a 和 VS2017 卡在“互不相认”
某开发者在 Windows 10 上同时装了 MATLAB R2017a 和 Visual Studio 2017,准备用 C++ 写一个 MEX 加速函数。结果mex -setup C++拉出来的编译器列表里只有 VS2015,新建的 VS2017 项目怎么都进不了 mex 的视野。这个标题里的"MATLAB R2017a 支持 Microsoft Visual Studio 2017补丁"就是为这个场景出现的:它不是一个新功能包,而是一层适配层,让老版本 MATLAB 的 mex 编译器发现逻辑认识新版 VS 的工具链,从而正常编译.mexw64。适合 Windows 平台、需要同时维护 MATLAB 脚本和 C++ 代码、或者准备从 VS2015 迁移到 VS2017 的开发者。读完你可以自己备份、安装、验证并排查这个补丁,不再被编译器列表卡住。
2. 为什么 R2017a 认不出 VS2017:mex 配置表与 vswhere 补丁原理
2.1 mex 是怎么发现编译器的:一张配置表引发的“黑匣子”
很多人在这一步直接把锅甩给“MATLAB 太老”,真实原因藏在 mex 的编译器发现机制里。mex启动后不会去环境变量 PATH 里全文搜索cl.exe,而是读取安装目录下的mexopts配置文件夹。在 Windows 上,这个文件夹位于matlabroot\bin\win64\mexopts,里面放着一批 XML 文件,每个 XML 对应一个官方验证过的编译器版本和架构。R2017a 发布时只验证到 VS2015,所以这个目录里默认只有 VS2013、VS2015 等配置文件,没有 VS2017 的条目。
当执行mex -setup C++时,MATLAB 解析这些 XML,在命令行或图形界面里列出可选项。列表里看不到 VS2017,不是 VS2017 没装好,也不是 MATLAB 安装损坏,而是 mex 的“白名单”里没有它。这个设计很像一个黑匣子:外部看是找不到编译器,内部看只是缺一条配置记录。理解这一点后,补丁的作用就清楚了:它做的事情就是往这张白名单里补上 VS2017 的条目,并让 mex 知道去哪个路径调用cl.exe。
从 R2017a 的角度看,VS2017 还有一个更麻烦的变化:VS2017 的安装布局不再固定在一个统一目录,而是通过vswhere.exe定位实例,并且可以并行安装 Community / Professional / Enterprise 多个版本。R2017a 原有的编译器探测脚本靠注册表旧路径,不认识 vswhere,所以即便 VS2017 装在默认位置,mex 也只会扫注册表里 VS2015 留下的键值。这也是为什么有人手动把 VS2017 的VC\Tools\MSVC路径加进 PATH 仍然没用——mex 读的是配置文件里的路径字段,不是 PATH。
| 项目 | VS2015 之前的发现方式 | VS2017 之后的发现方式 |
|---|---|---|
| 安装路径 | 固定注册表项 | vswhere + 实例查询 |
| 并行版本 | 基本只能装一个 | 可多版本共存 |
| SDK 路径 | 与 VS 捆绑 | 依赖 Windows 10 SDK |
| 编译器工具集 | VC14 固定版本号 | MSVC 版本目录不固定 |
这张表能帮你理解:补丁不是修 MATLAB,而是在新 VS 的安装形态和旧 MATLAB 的配置读取方式之间架桥。
2.2 补丁到底改了什么:mex 配置、SDK 版本与 C++ 工具集
补丁并不是把 MATLAB 升级到 R2017b,也不是给 MATLAB 安装 C++ 编译器,而是向mexopts目录里写入一组新的 XML 配置文件,并对 MATLAB 自带的编译脚本做少量修正。以常见的mex_C++_win64.xml为例,补丁后的文件会明确写清楚三块信息。
第一块是编译器位置。它告诉 mex 优先调用vswhere.exe去定位 VS2017 的安装实例,再解析出cl.exe所在的具体版本路径。第二块是编译参数。补丁把默认的COMPILER参数更新为适合 VS2017 的写法,比如增加/std:c++14的入口,而不是继续用老 VS 的默认标准。第三块是链接与 SDK 路径。VS2017 默认使用 Windows 10 SDK,它的头文件和库文件路径与 VS2015 自带的 SDK 不同,补丁会将INCLUDE、LIB和SDKS等变量指向新 SDK。
安装补丁时,脚本一般会先备份原mexopts目录,再写入新 XML。因此,如果补丁之后mex -setup多出一个Microsoft Visual C++ 2017选项,说明配置条目已经生效。但要注意:补丁只更新配置,不修改 MATLAB 核心库,所以不会影响其他用 VS2015 编译产生的 mex 文件。这是一个相对安全的小改动,但仍然建议保留备份,因为后续手动改mexopts时很容易把路径写坏。
2.3 补丁之前先确认:你的 R2017a 到底缺哪个编译器支持
动手打补丁前,我建议先跑一条 MATLAB 命令,确认当前状态,避免白忙一场。在命令窗执行mex.getCompilerConfigurations('C++','Installed'),如果返回[],说明 mex 当前没有任何 C++ 编译器配置;如果返回的是 VS2015 而不是 VS2017,说明 VS2017 配置缺失,正是补丁要处理的场景。
还要确认 VS2017 本身真的装了。打开 Visual Studio Installer 看是否有“使用 C++ 的桌面开发”工作负载,如果没有勾选 VC++ 工具集,补丁装了也没用。更直接的办法是检查cl.exe是否存在,一般位于C:\Program Files (x86)\Microsoft Visual Studio\2017\<版本>\VC\Tools\MSVC\<工具集版本>\bin\Hostx64\x64\cl.exe。只要这个文件存在,就说明编译器本体没问题,补丁值得打。
这里有一个容易误判的点:mex -setup看不到 VS2017 时,有人会去改环境变量 PATH 或手动设置MW_MEX_C_COMPILER,这种做法通常无效,因为 mex 的发现流程不走 PATH。改环境变量能解决的是“找到 cl.exe 但运行时缺少 dll”的问题,而不是“列表里根本没有 VS2017”的问题。补丁之前先分清你到底卡在哪一步,后面排错才顺手。
3. 安装 R2017a 支持 VS2017 的补丁:从备份到编译 Hello MEX
3.1 第一步:检查当前编译器识别状态
拿到补丁后不要急着双击,先在 MATLAB 命令窗里做一次快照。除了mex.getCompilerConfigurations,还要把mex -setup C++的输出留个底。命令行版执行:
mex -setup C++常见输出如下:
MEX configured to use 'Microsoft Visual C++ 2015 Professional (C)' for C language compilation.如果没有安装任何受支持的 C++ 编译器,则会提示找不到编译器,并列出可选的 SDK。保存这段输出,它能在补丁后做对比。同时建议执行一次ver,确认 MATLAB 是不是真的 R2017a,且没安装过别的编译支持包,避免补丁和已有配置冲突。
这一步的本质是建立当前环境的基线。很多翻车案例都是因为机器上装了不止一个 VS,或以前手动改过mexopts,补丁装上后把旧配置顶掉了,但mex仍缓存了旧的设置。基线记录能帮你快速判断是配置没生效,还是路径被覆盖。
3.2 第二步:以管理员身份安装补丁并更新配置
常见补丁包是一个.zip压缩包,解压后里面有安装脚本和若干.xml文件。安装前先关闭所有 MATLAB 窗口,以管理员身份运行安装脚本(有的叫setup.bat,有的叫install.bat)。脚本会检测matlabroot,常见安装位置是C:\Program Files\MATLAB\R2017a,然后把新的mex_C++_win64.xml等文件复制到bin\win64\mexopts。
我习惯在运行前先把整个mexopts目录复制一份到备份目录,这是后悔药,成本极低。命令如下:
copy "C:\Program Files\MATLAB\R2017a\bin\win64\mexopts" "%USERPROFILE%\mexopts_backup_R2017a" /Y这段命令把 mexopts 目录整体复制到当前用户目录下的备份文件夹,/Y表示不询问直接覆盖同名文件。备份后就算补丁脚本在覆盖过程中出错,也能一键还原。如果安装脚本要求指定 MATLAB 根目录,要把路径写成你的实际路径,不要照抄上面的占位路径。
补丁脚本运行完通常没有太多输出,最多提示Files copied successfully或Configuration updated。如果没有输出,不要慌,去mexopts目录看文件时间戳,确认刚才的 XML 是否真的更新了。判断脚本是否成功,比看脚本反馈更可靠。
3.3 第三步:重开 MATLAB 并让 mex -setup 认到 VS2017
补丁写入配置后,重新打开 MATLAB,让 mex 的配置缓存重新加载。还在当前会话里直接运行mex -setup的话,很多机器上仍然看不到 VS2017,这不是补丁没生效,而是 MATLAB 第一次启动时已经把mexopts目录的读取结果缓存到了内存和临时文件里。
重开后执行:
mex -setup C++如果补丁生效,输出应该变成:
MEX configured to use 'Microsoft Visual C++ 2017 (C)' for C language compilation.注意这里的版本名是2017,不是2017 Professional或2017 Community,补丁的配置文件一般只匹配 VS2017 整体。如果你看到的是 VS2015,说明补丁文件没有覆盖到正确的mexopts目录,或者是电脑上同时装了多个 VS,mex 选择了优先级更高的旧版配置。此时执行mex.getCompilerConfigurations('C++','Installed')查看所有可用的编译器配置列表,确认 VS2017 到底在不在列表里。
如果重开后还是只看到 VS2015,但确认 XML 文件已经写入,那么尝试在 MATLAB 命令窗执行mex -setup时不带C++参数,有时图形交互界面的列表比命令行更完整。另一个常见做法是删除%APPDATA%\MathWorks\MATLAB\R2017a下的 mex 缓存文件,再重开 MATLAB。缓存清理后配置会在下次启动时重新扫描。
3.4 第四步:编译第一个 MEX 文件验证链路
配置选到 VS2017 后,立刻写一个最小 C++ 文件验证整个链路。下面是经典 Hello World 写法:
#include "mex.h" void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // nlhs/plhs/nrhs/prhs 是 MEX 函数的固定入口参数 // 本项目不使用它们,先全部 void,避免编译器告警 (void)nlhs; (void)plhs; (void)nrhs; (void)prhs; mexPrintf("R2017a + VS2017 mex OK\n"); }保存为hello.cpp,然后在 MATLAB 命令窗编译:
mex -R2017a hello.cpp-R2017a参数启用 R2017a 的 MEX API 兼容模式,生成的文件可以跨小版本加载。如果编译没有报错,再运行:
hello看到R2017a + VS2017 mex OK就说明补丁真的打通了链路。没有输出或报错时,按mex -v的详细日志排查,后面第 5 章会展开。
4. 把补丁效果调稳:MEX 编译参数与 VS2017 工具集设置
4.1 关键参数:-R2017a、-std=c++14 与输出命名
补丁装好后,mex 默认就能编译了,但实际项目里还需要考虑几个参数。-R2017a不是必须的,但强烈建议加。它的作用是让生成的 MEX 文件声明一个最低版本,只支持 R2017a 之后的 MATLAB 加载,而不是默认的兼容所有旧版本。对于只在本机 R2017a 上运行的程序,加这个参数能让编译器少做一层兼容处理,后续再用 VS2017 的 C++14 特性也更顺畅。
C++ 标准参数要特别留意。VS2017 默认编译器标准是 C++14,但 mex 配置里可能没有显式传/std:c++14。如果你要在代码里使用std::optional或结构化绑定,就需要在编译时显式指定。可以用下面的方式覆盖编译器参数:
mex -R2017a COMPFLAGS="$COMPFLAGS /std:c++17" hello.cpp$COMPFLAGS是 mex 预留的宏,把配置文件里的原有编译参数展开再拼接/std:c++17,因此不会丢失默认的警告和优化选项。但要注意,R2017a 的 mex 头文件是按 C++14 设计的,用 C++17 编译能过,运行时如果依赖新版标准库行为,就要确认mexw64是在 VS2017 的运行时环境中运行。建议项目默认用 C++14,除非你有明确需求。
输出文件命名也一样,mex 默认会把hello.cpp编译成hello.mexw64,但如果你用-output指定了别的名字,需要保证输出名和 MATLAB 函数名一致,否则调用时找不到。用-outdir可以把生成的 mex 文件放到指定目录,方便工程化管理。
| mex 参数 | 作用 | 我的建议 |
|---|---|---|
-R2017a | 限定 MEX 目标 API 版本 | 常用 |
-outdir | 指定 mex 文件输出目录 | 工程常用 |
-output | 重命名输出文件 | 慎用,需与函数名一致 |
-v | 打印完整编译日志 | 排错必开 |
COMPFLAGS | 附加编译器参数 | 需要 C++17 时使用 |
4.2 环境变量与 Windows SDK 版本选择
补丁的配置文件里通常硬编码了 VS2017 和 Windows SDK 的匹配关系。如果你的机器装了多个 Windows SDK 版本,mex 编译时可能报错说找不到 SDK,或者在日志里看到INCLUDE变量指向一个不存在的目录。这时候你要在 Windows 的“系统属性”-“环境变量”里检查INCLUDE和LIB是否指向了正确 SDK。
但最稳的办法不是设置全局环境变量,而是让 mex 的配置文件自动寻找 SDK。补丁脚本一般会调用vswhere并读取注册表中 SDK 的当前版本。如果你后来升级了 Windows SDK,补丁里记录的版本可能过期。此时可以手动打开mex_C++_win64.xml,找到类似<SDKS>或<WindowsSDKVersion>的变量,改成你实际安装的 SDK 版本。
修改前先备份 XML。改完不用重装补丁,只需重开 MATLAB 让配置重新加载。验证方法是执行mex -v hello.cpp,在输出里搜索INCLUDE,确认路径里有10.0.开头的 SDK 目录。新版 SDK 路径一般长这样:C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt,如果你的项目用的是这个版本,路径就会出现在日志里;如果没出现,说明INCLUDE被其他环境变量覆盖了。
另外,不要在系统环境变量里手动添加一个过时的 SDK 路径,那样会让 mex 优先读到旧头文件,产生“混合 SDK”的诡异报错。最好的做法是清理掉与 MATLAB 无关的INCLUDE、LIB全局变量,完全交给补丁配置文件管理。
4.3 让 VS2017 的 C++17 特性在 R2017a 里安全使用
这里有一个很多人踩过的坑:补丁让 mex 编译器支持了 VS2017,但 MATLAB R2017a 进程本身还是用老版本的 VC++ 运行库加载的。VS2017 默认动态链接/MD到vcruntime140.dll和msvcp140.dll,如果操作系统上的 DLL 版本比 VS2017 还老,就会在加载 mex 时弹窗“找不到 VCRUNTIME140.dll”或“找不到 MSVCP140.dll”。
解决方法是安装 VS2017 对应的 Visual C++ Redistributable,确保系统里有足够新的运行库。如果代码里用到了 C++17 标准库,比如std::filesystem,链接阶段还会需要额外的符号,这时要么用 VS2017 的/std:c++17参数编译,要么在mex命令里通过-l手动链接需要的系统库。
对于写 mex 多线程代码的情况,我建议保留默认的/MD,不要改成/MT静态链接。静态链接会把 VC++ 运行库复制进 mex 文件,看起来解决了依赖,但 MATLAB 里其他模块(包括 MATLAB 自己)都加载了动态运行库,两种运行库同时存在于同一个进程,容易造成内存分配和释放的混乱,轻则崩溃,重则挂掉整个 MATLAB。补丁之后保持动态链接,是更安全的习惯。
如果代码需要兼容 R2017a 和更新的 MATLAB 版本,还要关注 MATLAB 头文件里的mxArray布局。R2017a 默认使用互操作 API,-R2017a会让 mex 文件声明这个 API 版本,避免在高版本 MATLAB 中被判定为过老而拒绝加载。TS接口的mxArray和matlab::data::Array混用时,建议在 mexFunction 里统一转换成 MATLAB 数据类型,不要跨 layer 直接操作。
5. 补丁落地后的避坑清单:5 个翻车现场与排查命令
5.1 现象:mex -setup 仍看不到 VS2017
原因:最常见是安装补丁后没有重开 MATLAB,配置缓存还停留在启动时读到的旧列表。另一个原因是 MATLAB 以管理员身份运行,而 vswhere 在当前用户上下文找不到 VS2017 实例,或者安装的是 VS2017 预览版,补丁的正则表达式只匹配正式版。
解决:先重开 MATLAB;如果还是看不到,以非管理员方式运行一次;再不行,在命令窗执行mex -setup C++ -v,看日志里vswhere的调用路径和输出。预览版 VS 可以改mex_C++_win64.xml里的版本匹配规则,但最好直接安装正式的 VS2017 更新版本,避免给自己埋雷。
在 MATLAB 里还可以执行:
mex.getCompilerConfigurations('C++','Details')这个命令会返回一个数组,里面每一项包含Name、Location、Version字段。如果数组里有Microsoft Visual C++ 2017,说明补丁已经生效;如果只有旧版本,那问题在配置覆盖;如果整个数组为空,问题在补丁根本没被加载。
5.2 现象:编译报错 “'cl.exe' 不是内部或外部命令”
原因:补丁已经让 mex 找到了编译器配置,但配置里写的cl.exe路径不对,或者 MATLAB 启动时没有执行 VS 的环境初始化脚本,导致当前进程中 PATH 不包含 VC 工具集目录。报错信息往往在命令输出中间,很容易被忽略。
解决:用管理员身份打开一个 cmd,进入 VS2017 安装目录运行vcvarsall.bat x64,然后再启动 MATLAB,这样 MATLAB 继承的环境里就有 cl.exe 路径。更持久的方法是修改mex_C++_win64.xml里的<CL>和<COMPILER>路径为实际绝对路径,但注意如果 VS 更新了工具集版本,这个路径会变,所以优先用相对查找而非写死。
运行vcvarsall.bat的示例:
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64要在同一 cmd 窗口里启动 MATLAB:
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 matlab这样启动的 MATLAB 会从父进程继承完整的 VS2017 环境变量,cl.exe和link.exe都能被 mex 找到。这个方法对补丁脚本失效的情况特别有效。
5.3 现象:链接失败或提示找不到 vcruntime140.dll
原因:VS2017 的编译器编译通过,但链接器需要 vcruntime 和 msvcp 的导入库,而补丁的 LIB 路径没有包含 VS2017 的VC\Redist\MSVC目录,或者系统缺少 VS2017 Redistributable 运行库。报错表现是LINK : fatal error LNK1104: cannot open file 'vcruntime.lib'。
解决:先检查mexopts配置里的LIB变量是否指向C:\Program Files (x86)\Microsoft Visual Studio\2017\<版本>\VC\Tools\MSVC\<工具集版本>\lib\x64;然后再安装 VC_redist.x64.exe。如果没有管理员权限,可以把 vcruntime140.dll 复制到 mex 文件的输出目录,但不建议长期依赖,因为 DLL 版本冲突更容易在别的机器上爆发。
排查时可以用系统工具确认 dll 是否存在:
where vcruntime140.dll where msvcp140.dll如果系统目录里存在,但 MATLAB 还是找不到,很可能是 PATH 里有另一个旧目录排在了前面。在 MATLAB 里执行getenv('PATH'),检查系统目录是否在列表靠前的位置,必要时手动调整。
5.4 现象:mex 编译成功但运行时崩溃
原因:补丁本身一般不会引起运行崩溃,崩溃通常来自代码里的 MEX API 误用。比如plhs[0]没有初始化就直接写入,或者把 C++ 异常从mexFunction抛出,MATLAB 只处理它认识的错误,C++ 异常一路传回会造成进程崩溃。
解决:在mexFunction最外层包一个try-catch,捕获所有异常后转成mexErrMsgIdAndTxt。同时用mex -v编译,确认是否用了-O2导致优化掉未初始化变量。如果补丁前用 VS2015 编译的 mex 没崩溃、补丁后换成 VS2017 才崩,优先检查代码里有没有依赖std::vector的实现细节,运行库不同会导致行为不同。
一个安全的 MEX 异常处理模板:
#include "mex.h" #include <exception> void doWork() { // 你的实际逻辑 } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { try { doWork(); } catch (const std::exception& e) { mexErrMsgIdAndTxt("mex:cppException", e.what()); } catch (...) { mexErrMsgIdAndTxt("mex:unknownException", "unknown error"); } }这段代码能保证 C++ 异常不会越过 mexFunction 边界,避免 MATLAB 直接崩溃。补丁后换了编译器,异常边界的处理方式会变得更敏感,早加早安心。
5.5 现象:补丁打了之后,其他 MATLAB 版本又认不出编译器了
原因:很多补丁脚本会扫描机器的matlabroot下的所有版本,并把新 XML 写进每一个版本的mexopts。如果你同时装了 R2015b 和 R2017a,补丁可能把 R2015b 的配置也覆盖了,但 R2015b 默认只支持 VS2013/VS2015,新配置反而让旧版 mex 无法选择正确编译器。
解决:安装补丁时,只选择 R2017a 的matlabroot,不要选“所有版本”;如果已经覆盖,用第 3.2 节的备份还原其他版本的mexopts。以后升级补丁时,先看脚本是否支持指定版本目录,不支持就手动拷贝 XML 文件到目标目录,而不是全局运行。
手动拷贝的替代方案,在 cmd 里执行:
copy "%USERPROFILE%\mexopts_backup_R2017a\*.xml" "C:\Program Files\MATLAB\R2015b\bin\win64\mexopts\" /Y这个命令会把备份的旧 XML 重新复制到 R2015b 的配置目录,恢复它原来的编译器支持。记住:补丁只是针对 R2017a 的适配,不是通用编译器升级包。
6. 进阶:用 R2017a 补丁后的 VS2017 打通 CMake 与 mex 联合构建
6.1 从 mex 到 CMake:把 VS2017 的编译器导出为 CMake 工具链
当你的项目不再只是一个.cpp,而是有第三方库、多目录源文件时,直接用mex命令行编译会越来越难维护。补丁之后的 VS2017 编译器完全可以交给 CMake 管理。常见做法是在 MATLAB 里先mex -setup C++确认编译器可用,然后在 CMake 里指定生成器为Visual Studio 15 2017 Win64,再用自定义命令把生成的 DLL 改名成.mexw64。
一个极简 CMakeLists 长这样:
cmake_minimum_required(VERSION 3.10) project(mex_demo LANGUAGES CXX) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(mex_demo SHARED src/demo.cpp) target_include_directories(mex_demo PRIVATE "${MATLAB_ROOT}/extern/include") target_link_libraries(mex_demo PRIVATE "${MATLAB_ROOT}/extern/libs/win64/microsoft/libMatlabDataArray.lib") set_target_properties(mex_demo PROPERTIES PREFIX "" OUTPUT_NAME "demo")PREFIX ""是为了避免 CMake 在生成 DLL 时默认加lib前缀,OUTPUT_NAME让输出叫demo.dll,再手动把生成的demo.dll复制为demo.mexw64。这里的MATLAB_ROOT要你在 CMake 配置时通过-DMATLAB_ROOT=...传入,对应 R2017a 的安装目录。这种方式让 C++ 代码可以用任意构建系统管理,MATLAB 只负责最终加载,特别适合混合开发。
6.2 验证补丁是否真的被 mex 使用:编译日志里的细节
判断补丁是否真正起作用,不要只看mex -setup列表。执行一次带-v的编译,日志里会打出实际调用的cl.exe路径、编译参数、INCLUDE和LIB。这段日志信息远比“编译器配置成功”更有价值。
mex -v -R2017a hello.cpp日志中Using Microsoft Visual C++ 2017是补丁写入的字符串。往下看Additional Include Directories如果出现VC\Tools\MSVC和Windows Kits\10\Include,说明 SDK 路径正确。若日志里的工具集版本是14.16,而 VS2017 更新到14.29,说明配置里还残留旧路径,可以手动更新 XML。
我常用这条命令把日志存成文本,跟补丁安装前的基线对比:
diary('mex_build.log') mex -v -R2017a hello.cpp diary off对比两次日志里的编译器和 SDK 路径,能快速发现补丁是否生效、以及是哪一条配置路径被覆盖。
6.3 一个踩坑习惯:把补丁和编译器版本写进 README
最后分享一个让我少折腾很多次的习惯。每次打完补丁,我会在项目根目录的 README 里记下三行:
Compiler : Visual Studio 2017 (MSVC 14.16) mex config file : matlabroot/bin/win64/mexopts/mex_C++_win64.xml Backup path : %USERPROFILE%/mexopts_backup_R2017a听起来很小儿科,但 C++ 库和 MATLAB 混用项目最怕的就是“在我电脑上是好的”。同事如果用了 VS2019,他会发现 mex 配置完全不匹配,就得先看 README 决定是否重建环境。把编译器版本、补丁的配置文件路径写清楚,比在群里瞎猜快得多。有一次我在代码里用了std::filesystem,只在 VS2017 的 C++17 模式下编译通过,同事用默认 C++14 编译直接报错,我靠 README 记录的工具集版本才定位到问题。
补丁解决的问题是让 R2017a 和 VS2017 在 mex 层面达成一致,但真正的坑总是藏在之后的参数、运行库和工程构建里。如果你已经准备把老 MATLAB 和新 VS 组合起来用,建议按第 3 章步骤做一次完整验证,再按第 4 章把参数固定下来。希望帮到你。
本文还有配套的精品资源,点击获取