轉 Visual C++6.0 與matlab聯合編程(2)----Visual C++6.0 環境下編譯和調試MEX文件


 

我的最初想法是利用matlab的mex命令調用C++程序生成動態鏈接庫的,但是測試程序(文中另附)通過了,自己的實際應用程序卻沒有過。還是把方法貼在這兒,以便自己以后進行整理。

http://shijuanfeng.blogbus.com/logs/106781870.html

以下內容來自上面博客,自己根據實際情況略作解釋改動。

  • MATLAB要調用C++程序步驟:

1. 在MATLAB命令行敲:mex -setup,選擇你所使用的C++版本,裝上mex(參考下面“2.MATLAB設置”)
2. 用“mex [參數] *.cpp”, eg:mex -O -c svm.cpp
這時在當前目錄下就會生成*.mexw32,*.mexw64的文件,這個文件類似於c++的dll文件,MATLAB可以直接調用。

當前,上述的cpp文件不是我們平時所寫的以main函數為入口,而是是mexFunction函數為入口,當然,還有其他不同,以下會進一步說明。

Mex文件的產生和調試(版本:VC++6.0和MATLAB7.0)

1 、 VC++6.0 環境及工程設置

      在上面的 VC 工程中,進行以下設置

(1) VC++6.0 環境設置

單擊菜單 Tools ,單擊 Options… 菜單項,出現 Options 對話框,選擇 Directories 標簽,在 include files 里面加入:

C:\MATLAB6P5\EXTERN\INCLUDE(就是你自己的matlab安裝路徑)

在 Library files 里面加入:

C:\MATLAB6P5\EXTERN\LIB\WIN32\MICROSOFT\MSVC60

2) VC++6.0 工程設置

單擊菜單 Project ,單擊 Setting… 菜單項,出現 Project Setting 對話框,選擇 Link 標簽,在 Object/library modules: 下面的文本框內容的后面加入 libmx.lib libmex.lib libmat.lib 

設置完成。

2.MATLAB設置:

(1) mex 命令設置

(a) 運行 Matlab ,在 Matlab 的命令窗口 (Command Window) 鍵入“ mex -setup ”命令后,按回車鍵,安裝 Matlab 編譯器;

(b) 命令窗口出現如下提示:

Please choose your compiler for building external interface (MEX) files:

Would you like mex to locate installed compilers [y]/n?

此時鍵入 ”y” ,按回車;

(c) 命令窗口出現如下提示:

Please choose your compiler for building external interface (MEX) files:

Would you like mex to locate installed compilers [y]/n? y

Select a compiler:

[1] Digital Visual Fortran version 6.0 in C:\Program Files\Microsoft Visual Studio

[2] Lcc C version 2.4 in C:\MATLAB6P5\sys\lcc

[3] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio

[0] None

此時鍵入 ” 3” ,按回車;選擇 Microsoft Visual C++6.0 的編譯器

(d) 命令窗口出現如下提示:

Please verify your choices:

Compiler: Microsoft Visual C/C++ 6.0

Location: C:\Program Files\Microsoft Visual Studio

Are these correct?([y]/n):

此時鍵入 ”y” ,按回車;確認選擇 Microsoft Visual C++6.0 的編譯器

(3) mbuild 命令設置

(a) 運行 Matlab ,在 Matlab 的命令窗口 (Command Window) 鍵入“ mbuild -setup ”命令后,按回車鍵,安裝 Matlab 編譯器;

(b) 命令窗口出現如下提示:

Please choose your compiler for building standalone MATLAB applications:

Would you like mbuild to locate installed compilers [y]/n?

此時鍵入 ”y” ,按回車;

(c) 命令窗口出現如下提示:

[1] Lcc C version 2.4 in C:\MATLAB6P5\sys\lcc

[2] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio

[0] None

此時鍵入 ” 2” ,按回車;選擇 Microsoft Visual C++6.0 的編譯器

(d) 命令窗口出現如下提示:

Please verify your choices:

Compiler: Microsoft Visual C/C++ 6.0

Location: C:\Program Files\Microsoft Visual Studio

Are these correct?([y]/n):

此時鍵入 ”y” ,按回車;確認選擇 Microsoft Visual C++6.0 的編譯器

(4) 在 Matlab 的命令窗口 (Command Window) 鍵入cd(prefdir); savepath prefdir;就可以了,其他版本未知。

3.添加 mexFunction 函數代碼

http://blog.sina.com.cn/s/blog_715d0ae30100rtd5.html

這部分參考的是以上博客的代碼,解釋的很清楚

1、函數的形式必須是

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

nlhs:輸出參數個數  plhs:輸出參數列表    nrhs:輸入參數個數 prhs:輸入參數列表

不過函數名可以隨便取的。注意:保存的文件名就是將來在MATLAB中調用的函數名,而不是這里的函數名。

下面給出一個例子,目的是想截取數組的部分元素組成新的數組

輸入參數3個,目標數組,截取的行(向量),截取的列(向量) 輸出參數2個,截取后數組,數組維數信息

在函數中展示了如何傳入傳出參數,以及如果從參數列表中取出每一個參數,MATLAB數據和C++數據的互相轉換,還有一些輸出函數等。

新建一個ResizeArray.cpp文件(ResizeArray將作為MATLAB調用的函數名),寫入下面代碼

復制代碼

#include "mex.h" 
//author: 汪幫主 2010.05.05
//MATLAB調用形式: [resizedArr, resizedDims] = ResizeArray(arr, selRows, sekCols)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 
    if (nrhs != 3)
    {
        mexErrMsgTxt("參數個數不正確!");
    }
    
    int rowNum = mxGetM(prhs[0]);
    int colNum = mxGetN(prhs[0]);
    double* pArr = (double*)mxGetPr(prhs[0]);
    //得到選擇的行列信息
    //無論是行向量還是列向量均支持
    double* pSelRows = (double*)mxGetPr(prhs[1]);
    double* pSelCols = (double*)mxGetPr(prhs[2]);
    int selRowsRowNum = mxGetM(prhs[1]);
    int selRowsColNum = mxGetN(prhs[1]);
    if (selRowsRowNum!=1 && selRowsColNum!=1)
    {
        mexErrMsgTxt("行參數不正確!");
    }
    int selRowsNum = selRowsRowNum*selRowsColNum;
    
    
    int selColsRowNum = mxGetM(prhs[2]);
    int selColsColNum = mxGetN(prhs[2]);
    if (selColsRowNum!=1 && selColsColNum!=1)
    {
        mexErrMsgTxt("列參數不正確!");
    }
    int selColsNum = selColsRowNum*selColsColNum;
    
    plhs[1] = mxCreateDoubleMatrix(2, 1, mxREAL);
    double* resizedDims = (double*)mxGetPr(plhs[1]);
    resizedDims[0] = selRowsNum;
    resizedDims[1] = selColsNum;    
    
    plhs[0] = mxCreateDoubleMatrix(selRowsNum, selColsNum, mxREAL);
    double* pResizedArr =(double*)mxGetPr(plhs[0]);
    
    //這里因為MATLAB中數據得按列優先
#define ARR(row,col) pArr[(col)*rowNum+row]
#define RARR(row,col) pResizedArr[(col)*selRowsNum+row]
    for(int ri=0; ri<selRowsNum; ri++)
    {
        for(int ci=0; ci<selColsNum; ci++)
        {
            RARR(ri,ci)=ARR((int)pSelRows[ri]-1,(int)pSelCols[ci]-1);
        }
    }
    
    mexPrintf("OK!\n"); 
}

復制代碼

2、編譯C++函數為MEX函數
將ResizeArray.cpp放在MATLAB當前目錄中,在MATLAB中輸入mex ResizeArray.cpp,編譯成功后將會生成ResizeArray.mexW32

3、在matlab中調用函數

arr=[11:19;21:29;31:39;41:49;51:59;61:69];
selRows=[1 3];
selCols=[2:4 5 9];
[rarr,rdims]=ResizeArray(arr,selRows,selCols)

4、運行結果

復制代碼

rarr =

    12    13    14    15    19
    32    33    34    35    39


rdims =

     2
     5

復制代碼

運行成功!!

 

 

這部分參考的是一篇博客的內容,經證實是可行的。

附上源博客地址:http://hi.baidu.com/welcomeclark/item/ff333321af845f8a6f2cc3c0

我自己的實驗結果:

1.設置Visual C++6.0編譯環境,添加相應的頭文件和庫文件的路徑。打開菜單->工具->選項。

2.設置系統的環境變量path,添加E:\program\MATLAB\bin\win32(注:這一部分可不用添加,一般安裝matlab程序的時候,是設置好了的)

3.創建Win32 Dynamic-Link Library工程實現mex文件。

4.創建CPP文件。 (這里就是你要實現的函數主體部分)

5.向工程添加DEF文件

添加內容:

LIBRARY "mexdemo1"

EXPORTS

      mexFunction @1

6.設置工程,鏈接中對象/庫模塊添加libmx.lib libmat.lib libmex.lib。

7.設置動態庫的調試路徑。

在調試中添加E:\program\MATLAB\bin\win32\MATLAB.exe

8.調試程序。使用快捷鍵F5或go圖標。彈出對話框

在Matlab中輸入如下命令,就可以進行程序調試。

注:cd 指的是定位到某個文件夾,接下來就是在matlab中調用函數的命令,根據具體函數名而定。

還可以在 mexFunction 源程序中合適的設置斷點,然后按 F5 鍵進入調試過程 。在 Matlab 命令窗口調用 **.dll ,程序就會停在 VC++6.0 環境里的程序斷點處。此時可以 在 Context 窗口中看到最近處理的變量數值 ,並可以 隨意添加 Watch 。這樣就可以像調試通常的 C 程序一樣對 mex 程序進行調試。

注意:若出現LINK : fatal error LNK1104: cannot open file "libmx.lib"問題,請檢查庫文件是否正確添加。

 

 

在前面一篇文章Visual C++ 6.0與matlab聯合編程(2)中,利用VC++生成了DLL文件,但是一般matlab命令生成的DLL文件名后綴為mexw32,我們可以利用def文件導出mexFunction函數。這里,我參考了另一篇博客,但是他的環境是2008,在VC6.0里設置也很簡單。

在上面的Output file name中將輸出文件的后綴名改為mexw32就可以了。


免責聲明!

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



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