C++和Matlab混合編程——MATLAB調用c++函數(以svmlight爲例)

遇到這個問題是因爲在使用別人的代碼包的時候,人家編寫好的是mexw32,而我的系統是64位。當時沒有注意到人家把c++源碼給了,只要在對應路徑下mex a.cpp
即可得到a.mexw64。


最近由於在看svm的相關內容,用到了svmlight的包,涉及到了MATLAB和c++的混合編程。對於mex的一些東西,浪費了好幾天時間來調試,今天稍微整理一下。
這是下載好的svm_mex包中的c源文件的內容:
這裏寫圖片描述
事實上在svmlight的源文件包中,是沒有上圖中mex開頭的幾個文件的。這幾個文件是爲了實現MATLAB和c++的混合編程,後來寫進去的。但是一般下載下來的svm_mex包,比較老的都是在Linux下編譯的或者是32位編譯的,也就是說,只有下面的這些文件:
這裏寫圖片描述
我的機器是64位windows,根本用不了,所以需要自己編譯。也就是說,目標是生成下列文件:
這裏寫圖片描述
這裏我嘗試直接在MATLAB下對mexsvmlearn.c(因爲需要的函數從該函數入口),使用
mex -g mexsvmlearn.c xxx.c qqq.c aaa.c來執行,但是總是會報錯。
一開始總是報錯爲svm_commom.h文件中的sizeof函數,但是該文件中並沒有調用該函數,報錯行有一個isnan函數。將其註釋,以及對應的svm_commom.c文件中的對應行註釋掉之後便不在報錯。
但是,在MATLAB裏使用mex命令進行編譯還是出錯,後來使用了下載的包中帶的bat文件進行編譯就生成了mexw64文件。但是這裏還是有問題。
這裏寫圖片描述
原install.bat文件中,這裏的第二行patch前面沒有rem這個標識符。我對於腳本文件不熟悉,因爲它總是報錯所以就加上了這個rem標識符,後面就不再報錯,能夠生成我想要的mexw64文件了,但是會提示,找不到xxx.exp文件。這邊我也不是很懂,但是似乎對於mexw64文件的使用不會有影響。

這裏進行編譯實際上主要是運行了以下幾個語句:

cmd /c mex -g -DMATLAB_MEX -DMEX_MEMORY -I../src ../src/mexsvmlearn.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.c

cmd /c mex -O  -DMATLAB_MEX -DMEX_MEMORY -I../src  ../src/mexsvmclassify.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.c

cmd /c mex -O  -DMATLAB_MEX -DMEX_MEMORY -I../src ../src/mexsinglekernel.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.c

cmd /c mex -O  -DMATLAB_MEX -DMEX_MEMORY -I../src ../src/mexkernel.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.c

這裏的DMATLAB_MEX 我沒查到是什麼意義。-g命令是爲了後面和debug有關係,如果不加的話不會生成mexw64.pdb文件,也無法進入vs調試。-O好像是和編譯優化有關係吧。

然後生成了mexw64文件就可以調用了。先不說我函數調用後來出錯的問題。。。(爲什麼總是這麼多問題),下面整理一下MATLAB調用c++函數時在vs裏的調試問題
主要參考該教程:https://cn.mathworks.com/matlabcentral/answers/100603-how-can-i-compile-a-matlab-engine-application-using-microsoft-visual-studio-9-0-or-10-0

該教程翻譯整理如下:
1. 打開vs,選擇文件->新建->項目,然後選擇Visual C++->General->空項目
2. 右擊源文件,選擇添加新建項,新建一個cpp文件,然後將想要調試的c++文件內容拷貝進來。(這裏我不是新建項,而是導入一個現有項,也是可以的。)
下面是相關環境的配置,重要。
3. 右擊解決方案,進入屬性頁。
a. C/C++中的“附加包含目錄”內,加入該路徑

$MATLABROOT\extern\include

這裏寫圖片描述
【這一步我實際上沒有加,我在VC++目錄裏面對包含目錄和庫目錄進行了配置,好像也是沒有問題的。】
b. “C/C++預編譯頭”選項中,選擇“不使用預編譯頭”
這裏寫圖片描述
c. 鏈接器的“附加庫目錄”中加入MATLAB的目錄,對於64位系統來說:

$MATLABROOT\extern\lib\win64\microsoft

這裏寫圖片描述
d. 配置屬性->調試加入環境目標路徑,格式如下:

PATH=$matlabroot\bin\win64
  1. 鏈接器->輸入中,加入下列附加依賴項:
libmx.lib

libmat.lib

libeng.lib

5.【這一步我不太懂,點進連接只是一個文檔。我下載打開了,似乎沒什麼意義。】原文:If compiling on 64-bit Windows, change the target to x64 as mentioned on the following link
http://msdn2.microsoft.com/en-us/library/9yb4317s(VS.80).aspx
You should now be able to build the executable.

6 . 環境變量配置。這裏注意配置系統環境變量(下面的那個Path)爲:$MATLABROOT\bin\win64
7. 後面就可以運行並且調試目標代碼了。

發佈了48 篇原創文章 · 獲贊 17 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章