64位Mex文件在Matlab 2014b和Visual Studio 2013中的调试
转载自:http://blog.****.net/xuexiyanjiusheng/article/details/46862635
网上有很多关于VS调试mex文件的教程,不过他们的VS和Matlab版本都不高,一般得到的都是mexw32文件,并且还有些地方有错误。楼主借鉴了很多人的博客,并自己在Matlab 2014b和Visual Studio 2013上进行了尝试,列举出了所有可能出现的问题即解决方案,并给出了很详细的“傻瓜”教程,可以确保调试的正常进行。
matlab里面无法单步调试mex函数,故需转到VS上面调试,这里采用VS2013.
1、VC中编写Mex函数
新建一个win32 dll空项目。
创建项目: Win32->Win32项目,名称:ent
(这里项目的名称最好和要用的函数名称一样)
选择DLL (D) ->完成.
2、新建工程后,在源文件里面自动就有ent.cpp和ent.def。把之前编写好的MEX函数ent.cpp文件复制到系统生成的ent.cpp的#include"stdafx.h"之后。
3、配置项目属性。
l打开项目属性配置页 -> C++ -> 附加包含目录 加入MATLAB安装目录下的\extern\include 路径。
l连接器 -> 附加库目录 加入MATLAB的\extern\lib\win64\microsoft 路径。
l 连接器 -> 输入 -> 附加依赖项 输入libmx.liblibeng.lib libmat.lib libmex.lib这四个lib文件。
l 项目属性页 ->配置管理器 ->活动平台解决方案 ->新建解决方案平台 -> x64
(这里是参考了如下错误:
编译出现:
1>test.obj: error LNK2019:无法解析的外部符号_engClose,该符号在函数_main中被引用
1>test.obj : error LNK2019: 无法解析的外部符号_engSetVisible,该符号在函数_main中被引用
1>test.obj : error LNK2019: 无法解析的外部符号_mxDestroyArray,该符号在函数_main中被引用
1>test.obj : error LNK2019: 无法解析的外部符号_mxGetData,该符号在函数_main中被引用
这个问题如果你按照上述配置好的话,这就很有可能出在兼容问题上。因为2012b只提供64位版本,所有需要将vs工程变为64位。点击win32旁的下拉列表,选择配置管理器。在活动解决方案平台这里选择x64即可。重新编译一切ok。
)
l在Linker-General-OutputFile:改成
x64\Debug\ent.mexw64(32位系统相应改成32)
l项目属性页 -> 配置属性 -> 常规 -> 目标文件扩展名:改成 .mexw64
(这是参考了以下错误:
配置vs2010工程时,发现warning
warning MSB8012: TargetPath(...) does notmatch the Linker's OutputFile property value
运行时提示找不到可执行程序。后来发现的输出文件(Link.OutputFile )与debugging的command不一致,这一点与vs2005不同。网上找到的资料给出如下解释:
http://social.msdn.microsoft.com/Forums/en/vcprerelease/thread/3c03e730-6a0e-4ee4-a0d6-6a5c3ce4343c
Link.OutputFileis the value defined at Linker -> General -> Output File on the propertypage. By default, its value is $(OutDir)$(TargetName)$(TargetExt), which is thesame as the value of $(TargetPath). When we convert an application from aprevious version, however, there is not an easy way for conversion to parseLink.OutputFile to figure out what exactly the values are for $(TargetName) and$(TargetExt), as different customers may have formatted them in different ways.To work around that, we decided to preserve the value of Linker.OutputFileduring conversion. After conversion, $(TargetName) will default to$(ProjectName). $(TargetExt) will default to the default extension for theapplication type: .dll for Dynamic Library, .lib for Static Library and .exefor Application. Link.OutputFile value will be preserved. Warning MSB8012 willbe issued in the conversion log if Link.OutputFile and $(TargetPath) are notthe same. You will get the same warnings when building the application.
$(OutDir), $(TargetPath) and$(TargetExt) are exposed on the "General" property page, as"Output Directory", "Target Name", "TargetExtension", respectively. You can manually change the values of theseproperties so that you get the expected value for $(TargetName) or$(TargetPath) and no longer get the warning. Once you make the change, thebehavior should be pretty much the same as previous versions of Visual Studio.
Li Shao, MSFT
vs2010中,$(OutDir)、$(TargetName)、 $(TargetExt)等可在工程property pages->configuration properties->general中设置
lSource Files- Add - New Item新建模块定义文件-> 代码ent.def
并为其添加内容
LIBRARY;"ent"
EXPORTS mexFunction
l 在Linker-Input-ModuleDefinition File添加:ent.def
4、生成解决方案
如果以上都正确,便会在工程Debug目录下生成一个ent.mexw64文件。
5、在VS中单步调试MEX函数。
l将matlab的currentfolder 设置成mexw64文件所在的路径,即Debug目录。(这步非常重要,要不无法调试调用)
(由于我是在Matlab主函数里面调用的这个mex函数,所以要将其他的.m也拷到Debug目录中去)
l VS 2013-Tools-附加到进程 Attach to process-选择matlab 编辑器(由于我是在Matlab的编辑器里面来运行函数的,所以选择的是Matlab的编辑器)。
(附加到进程后,会加载较长一段时间的符号加载过程)
(为了PDB的成功加载,最好“设置”->“调试”->“符号”,选中“Microsoft符号服务器”)
l 在源代码ent.cpp里设置断点。
(注意,这时候会显示当前不会命中断点,还没有为该文档加载任何符号,直接忽略就行,等Matlab执行mex文件时就会中断的)
(当时楼主在这查教程查了半天,硬是改不好,后来发现是这样的,用Matlab运行到mex函数就会进去了)
l在matlab工程里运行mex函数,即会跳转到VS的断点处。然后按F10便可单步执行。
6、每次修改MexFunction所在的.cpp文件后,重新编译生成解决方案前都需要先在matlab工程下clear一下,即
clear ent.mexw64
注意:这步非常重要,因为matlab在调用该mex函数后还一直占用,未释放,必须要clear下,VS中才可重新编译生成解决方案。
(注意有的时候即使clear了之后,在重新生成解决方案时,还是出现ent.mexw64无法访问的情况,这时候关闭Matlab的同时,还要注意在任务管理里面把潜在的Matlab.exe的进程也结束掉才行。)
调试成功后把ent.mexw64文件copy到任意matlab工程里,就可以像函数调用一样任意使用。