【環境】VS2013和MATLAB相互調用混合編程


 

    Visual Studio和MATLAB混合編程,有兩種方法:

  1 MATLAB調用C程序;

  2 VS調用MATLAB(目前見到的都是VS,其他編譯器如codeblocks,或不提供這項功能);

    前一種是用MATLAB的mex命令調用VS或其他編譯器,將以一定方式編寫出的C文件編譯成.mexw32(針對win32)或者.mexw64(針對win64),然后MATLAB就可以用調用動態鏈接庫的方式,調用C程序。這一過程中,只需要在安裝好編譯器的前提下,執行:

mex -setup

mbuild -setup

並按照提示按部就班地幫助MATLAB找到C編譯器就可以了。遇到MATLAB找不到Visual Stdio的情況時,可按照官方網站提供的方法,例如如果MATLAB找不到已安裝的Visual Studio 2013,則在

http://www.mathworks.com/matlabcentral/fileexchange/44408-matlab-mex-support-for-visual-studio-2013--and-mbuild-

下載官方提供的文件,按照README的要求將文件復制到指定目錄下即可。

README:

The files 
  * msvc120engmatopts.bat
  * msvc120opts.bat
  * msvc120opts.stp
should be copied to C:\Program Files\MATLAB\R2013a\bin\win64\mexopts .

The files 
  * msvc120compp.bat
  * msvc120compp.stp
should be copied to C:\Program Files\MATLAB\R2013a\bin\win64\mbuildopts .

 

      另一種是反過來,由VS去調用MATLAB,因為歸根結底,許多底層的代碼都依賴於C/C++語言,如果要使用MATLAB進行實時的數據處理,那么必然是使用C/C++(從操作系統內核、套接字,或者設備)獲取數據,再調用MATLAB進行處理。切入正題:

     1   首先正確地安裝好環境,如下是我使用的環境:

    x86

    Windows 7 

    VS2013

    MATLAB R2010a(安裝目錄為D:\MATLAB\R2010a)。

     2    下面是VS路徑的包含

     右鍵項目—屬性—VC++目錄

               —包含目錄,添加D:\MATLAB\R2010a\extern\include;(注意分號)

               —庫目錄,添加D:\MATLAB\R2010a\extern\lib\win32\microsoft;

            —C/C++(—常規),添加附加包含目錄D:\MATLAB\R2010a\extern\include\;

          —鏈接器

               —常規,添加附加庫目錄D:\MATLAB\R2010a\extern\lib\win32\microsoft;

               —輸入,添加附加依賴項:libeng.lib;libmat.lib;libmex.lib;libmx.lib;mclmcrrt.lib;mclmcr.lib;

     3   系統環境變量:PATH里添加D:\MatLab\R2010a\bin\win32; 幫助VS找到MATLAB的提供的動態鏈接庫。

     4   注冊MATLAB服務器:cmd,在D:\MatLab\R2010a\bin目錄下運行

matlab \regserver

    大概是開啟MATLAB Server模式,接收VS的調用請求吧。

    5  下面寫C/C++程序:

    添加頭文件以及動態鏈接庫

#include "engine.h"

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libmat.lib")

    打開引擎(引擎用來調用MATLAB):

Engine* pEng = NULL;
    
    if (!(pEng = engOpen(NULL)))
    {
        printf("Open matlab enging fail!");
        getchar();
        return -1;
    }

    引擎打開函數openEng調用完畢后一定要檢查是否打開成功(類似雲malloc函數,申請完內存一定要檢查是否申請成功),因為就算pEng==NULL,在函數engEvalString執行中也不會拋出異常的,只會導致engGetVariable執行失敗,當然咯,因為根本沒執行嘛,哪來的variable?

    然后可以調用啦,一切的matlab命令都可以通過下面這個函數傳入MATLAB執行,類似於Linux的系統調用exec("...")和windows的system("..."):

engEvalString(pEng, "x=0:0.01:pi); y=sin(x); plot(x, y)");

    如果要得到MATLAB的返回結果:

engEvalString(pEng, "x=0:0.02:3.14; y=sin(x); plot(x, y)");
mxArray *x= engGetVariable(pEng, "x");
mxArray *y= engGetVariable(pEng, "y");
double * _x = mxGetPr(x);
double * _x = mxGetPr(y);
//此時_x為x數組,_y為y數組

    由於MATLAB里面,數據都將看成矩陣來處理,因此返回結果也是以Array的方式返回,如果是單個值,就是array[0],否則為array[0..n-1],如何得到n呢?還是用函數engGetVariable咯,可以先執行n=length(x),再將n傳回

    執行結束后,記得關閉引擎

 

if(pEng)
    engClose(pEng);

 

    注意一旦關閉,就不能再使用pEng了,否則會拋出異常。並且,在關閉引擎后,原本在執行過程中得到的figures也會關閉。在我的課題里面,引擎是在程序開始時打開,程序最終退出時才關閉。

 

6   如果在編譯期間出現“找不到XXX.lib”的情況,檢查路徑是否正確添加,不然就直接復制lib文件到system32吧。。。

7   如果編譯鏈接通過,運行起來還是有異常,檢查matlab server是否有注冊成功:運行matlab /regserver,再試一試。

8   因為調用MATLAB執行的命令是以字符串形式傳入的,千萬注意字符串里面的特殊符號、空格。特殊符號前面需要加上反斜桿,若有空格,依據MATLAB的語法,應使用單引號。例如:

engEvalString(pEng,"cd \'E:\\Desktop\\Alilce and Bob\' ");

 

9  如果遇到ERROR LNK2019,如:

錯誤    1    error LNK2019: 無法解析的外部符號 _mxGetPr,該符號在函數 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
錯誤    2    error LNK2019: 無法解析的外部符號 _mxDestroyArray,該符號在函數 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
錯誤    3    error LNK2019: 無法解析的外部符號 _engEvalString,該符號在函數 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
錯誤    4    error LNK2019: 無法解析的外部符號 _engOpen,該符號在函數 _main 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
錯誤    5    error LNK2019: 無法解析的外部符號 _engClose,該符號在函數 _main 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
錯誤    6    error LNK2019: 無法解析的外部符號 _engGetVariable,該符號在函數 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
錯誤    7    error LNK1120: 6 個無法解析的外部命令    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\Debug\matlab.exe    1    1    matlab

  檢查MATLAB和VS是否運行在同一平台上,如果MATLAB是x64,那么配置管理器中一定要選中x64,否則選Win32:

  右鍵項目——在配置管理器的下拉菜單里選中正確的平台,然后按照上面所述的過程重新配置路徑。

 

以上~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM