轉載自:http://blog.csdn.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工程裏,就可以像函數調用一樣任意使用。