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

(这里项目的名称最好和要用的函数名称一样)


64位Mex文件在Matlab 2014b和Visual Studio 2013中的调试
选择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 )与debuggingcommand不一致,这一点与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工程里,就可以像函数调用一样任意使用。