声明
本文的部分内容参考此文Mex文件在VS2010中调试方法中描述的方法试验得到,特此声明。
创建MEX工程
###Step 1: 在VS中创建MEX工程
- 如果新建工程,可以选择创建Win32 Project >> Application Type >> DLL;
- **如果是EXE工程(即应用程序工程,通常是默认生成类型),请修改Project属性为DLL。**具体操作步骤可以“如何将VS向导生成的DLL工程切换到EXE配置”中的描述进行逆向操作。
与普通的Windows程序类似,MEX文件也有一个专门的函数作为入口点。
void mexFunction( int nlhs, //number of left-hand-side, 即MEX函数输出参数
mxArray *plhs[], //包含mxArray指针的数组,即MEX函数的输出参数
int nrhs, //number of right-hand-side, 即MEX函数输入参数
const mxArray *prhs[] ) //包含mxArray指针的数组,即MEX函数的输入参数
{
// 此处放置MEX函数的处理代码
}
详细的说明可以参考Components of MEX File和mexFunction (C and Fortran),以及“MATLAB中mexFunction函数的接口规范”
###Step 2: 配置项目属性。
- 打开项目属性配置页,进行如下操作:VC++ Directories >> 加入“MATLAB安装目录 \extern\include”路径。
- 连接器 -> 附加库目录 加入"MATLAB的 \extern\lib<font color=darkred>win64\microsoft" 路径。
说明:
- 上文中“MATLAB安装目录”可以在MATLAB中输入
matlabroot
命令得到; - 路径中红色的部分对于32位系统是win32;
- Linker >> 输入 -> 附加依赖项 输入libmx.lib libeng.lib libmat.lib libmex.lib 这四个lib文件,配置位置如下图所示。
- Configuration Properties >> General >> Target Extension 改成
.mexw64
(此处如32位系统为mexw32
,下同)
- 增加 DEF文件定义导出函数名字(强制定义)
新建 DEF文件,此文件类型没有默认,可以新建文本文件后修改后缀为DEF。
文件中至少包含以下内容:
EXPORTS mexFunction
Linker >> Input >> Module Definition File中指定刚才新建的DEF文件:
#调试MEX工程
###Step 1: 测试MEX工程的配置
选择MEX工程,Build解决方案,如果以上都正确,便会在工程Debug目录下生成一个(ProjectName).mexw64文件。
###Step 2: 如何在VS中单步调试MEX函数?
- 将MATLAB的"current folder"设置成
mexw64
文件所在的路径,即Debug目录。(这步非常重要,否则无法正常调试) - VS >> Tools菜单 >> Attach to process >> MATLAB,在弹出对话框中选择"matlab.exe"。
- 在源代码中需要调试的位置设置断点,在MATLAB命令行窗口中输入MEX函数的名字(即mexw64文件的文件名,这里为ProjectName),即会激活调试过程并跳转到VS的断点处。
之后的操作与调试普通的C++程序(或者说普通的DLL程序)相同。
注意:每次修改MexFunction所在的.cpp文件后,建议重新编译生成解决方案前都需要先在MATLAB命令行窗口中执行clear命令,即:
clear (ProjectName).mexw64
此步骤的作用是让MATLAB在调用该mex函数后强制释放。执行clear命令之后,VS中才可重新编译生成解决方案。如果在操作的当前目录下,只有单一的MEX版本(即32位或64位版本),可以省略文件类型后缀,即:
clear (ProjectName)
如果忘记清理操作,可能会出现如下错误提示:
error LNK1168: cannot open D:\***\x64\Debug\DB***.mexw64 for writing D:\***\(YourProjectName)\LINK DB***
发布MEX程序
调试成功后把(ProjectName).mexw64文件拷贝到任意所需的MATLAB工程中,就可以像函数调用一样任意使用啦。
补记1(2018-04-02)
- 在调试过程中,如果因为出错导致MATLAB停止响应,可能会出现即使用调试工具中的“附加到进程”操作也无法激活调试。
此时,可以尝试按正常步骤关闭MATLAB以及Visual Studio,之后按上述的附加进程操作重新来过一次,常常可以解决问题。
这种情况多发生在程序中出现内存错误或者异常断点时。
补记2(2020-06-25)
随着美国政府对中国不友好态度甚嚣尘上,建议所有中国的开发者或者转向开源社区,或者从现在开始就要了解一下“去美国化”的开发手段。
因此MEX的混合编程,从长远看,不作为推荐的开发路径。使用Python作为首选的替代方法是应该郑重考虑的。
这些建议绝非耸人听闻,过十年再看这段话,就知道今日开始的努力必定不会白费。