C++與Matlab的混合編程

原文地址: http://blog.csdn.net/bendanban/article/details/37830495

=======================分割線以下爲正文================================


     Matlab 擁有豐富的功能,編程簡單。不過,有些情況下,Matlab程序的執行速度比較慢。C/C++編譯執行的程序速度比較快,編程難度上比Matlab要高一些。因此存在一種方案,就是使用Matlab實現我們的實驗程序,用C/C++來實現Matlab程序中比較耗時的部分,從Matlab程序中調用C/C++的程序以實現加速。

     本文主要講解如何在Matlab中調用C/C++的程序,以及如何編寫可供Matlab程序調用的C/C++程序。

     本文主要分以下幾部分:

     Hello Matlab,用一個簡單的例子來說明如何在Matlab中調用C/C++的程序,以及可供Matlab調用的C/C++程序應該注意哪些基本事項。

     Matlab調用C/C++程序傳遞參數。討論在C/C++中是如何使用Matlab傳來的參數的。

     Matlab與C/C++混合編程的方法論。給出在一般情況下使用Matlab與C/C++混合編程的方法步驟,讓大家有一個較爲清晰的應用此技術的思路。

     關於數據存儲的說明。說明數據在Matlab中的存儲方式。

     注意:本文認爲讀者會使用Matlab,掌握C/C++語言,並且有一臺計算機。計算機上安裝有Windows的操作系統,操作系統上裝有Matlab以及Visual Studio(比如VS2008,VS2010等)。或者計算機上安裝有Linux的操作系統,系統上裝有Matlab,GCC。


hello Matlab

     我們一步步完成一個叫“Hello Matlab”的程序。

     第一步:在你的計算機D盤下,創建一個目錄命名爲HiMat。在D:\HiMat目錄下創建一個文本文件,命名爲“abhimat.cpp”。將Code 1中的代碼拷貝到“abhimat.cpp”文件中,保存。(注意,這裏建立目錄以及命名等行爲不是規定的,只是爲了講解方便)。

  1. #include "mex.h"  
  2. void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])  
  3. {  
  4.   mexPrintf("hello matlab in C/CPP.\n");  
  5. }  
Code 1, abhimat.cpp

     “abhimat.cpp”就是將要在Matlab中被調用的C/C++代碼。

     第二步:在Matlab中編譯“abhimat.cpp”。啓動Matlab,進入D:\HiMat目錄,在Matlab命令窗口中執行code 2中的命令,根據提示完成C/C++編譯環境的配置。注意:如果你有多個編譯器,建議選擇最新的。

[plain] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mex -setup  
Code 2, 設置Matlab的C/C++編譯環境

     完成配置後,在Matlab中執行Code 3的命令來編譯abhimat.cpp。

[plain] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mex abhimat.cpp  
Code 3, 編譯abhimat.cpp

    第三步:執行編譯後的C/C++程序。在Matlab命令窗口輸入“abhimat”或者”abhimat()”,都可以調用編譯後的程序,推薦使用後者。

     細心的讀者已經注意到了:

  • 在Matlab中調用的C/C++函數名就是編譯後以mex*(這裏,*表示任意多個字符,例如mexw64)爲後綴名的文件名。
  • Matlab執行abhimat()命令後,實際執行的是mexFunction函數中的程序。

Matlab調用C/C++程序傳遞參數


    此節我們討論下,在供Matlab調用的C/C++程序中,我們是如何知道Matlab調用的參數類型、個數的。

    給出Matlab中調用C/C++程序的一個實例,如code 4所示。

[plain] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. c = [1 2;3 4;5 6];  
  2. d = [1 1;1 1;1 1];  
  3. [a, b] = abfunc(c, d);  
Code 4, Matlab調用C/C++程序實例

    下面的工作是如何在當前目錄下一個命名爲abfunc.cpp的文件中實現mexFunction函數。在這個函數中如何獲得Matlab命令中的c、d兩個變量的值,如何返回a、b兩個變量呢。

    注意mexFunction函數中的四個參數,一一作出說明:

    nlhs:mexFunction的第一個參數,它指示Matlab的調用命令中等號左側有幾個變量。例如,code 4中的調用,nlhs的值爲2,因爲它的等號左側有兩個變量,他們是a和b。

    plhs: mexFunction的第二個參數,它指示Matlab的調用命令中等號左側變量的指針。例如,code 4中的調用,plhs[0]表示的是a,plhs[1]表示的是b。

    nrhs:mexFunction的第三個參數,它指示Matlab的調用命令中等號右側的變量個數。例如,code 4中的調用,nrhs的值爲2,因爲它的等號右側有兩個變量,他們是c和d。

    prhs:mexFunction的第四個參數,它指示Matlab調用命令中等號右側的變量指針。例如,code 4中的調用,prhs[0]表示的是c,prhs[1]表示的是d。

    mxArrary是一個不可見的數據類型,是Matlab定義的,大家只需要知道mxArrary的指針與Matlab中的變量一一對應就可以了。

    下面實現abfunc.cpp,功能是a=c+d; b = c-d;具體代碼如code 5所示。

  1. #include "mex.h"  
  2. void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])  
  3. {  
  4.   double *p_c, *p_d;  
  5.   double *p_a, *p_b;  
  6.   
  7.   int c_rows, c_cols;  
  8.   int d_rows, d_cols;  
  9.     
  10.   int numEl;  
  11.   int n;  
  12.     
  13.   mxAssert(nlhs==2 && nrhs==2, "Error: number of variables");  
  14.   
  15.   c_rows = mxGetM(prhs[0]);// get rows of c  
  16.   c_cols = mxGetN(prhs[0]);// get cols of c  
  17.   d_rows = mxGetM(prhs[1]);// get rows of d  
  18.   d_cols = mxGetN(prhs[1]);// get cols of d  
  19.   
  20.   mxAssert(c_rows==d_rows && c_cols==d_cols, "Error: cols and rows");  
  21.   
  22.   // create output buffer  
  23.   plhs[0] = mxCreateDoubleMatrix(c_rows, c_cols, mxREAL);  
  24.   plhs[1] = mxCreateDoubleMatrix(c_rows, c_cols, mxREAL);  
  25.   
  26.   // get buffer pointers  
  27.   p_a = (double*)mxGetData(plhs[0]);  
  28.   p_b = (double*)mxGetData(plhs[1]);  
  29.   p_c = (double*)mxGetData(prhs[0]);  
  30.   p_d = (double*)mxGetData(prhs[1]);  
  31.   
  32.   // compute a = c + d; b = c - d;  
  33.   numEl = c_rows*c_cols;  
  34.   for (n = 0; n < numEl; n++)  
  35.   {  
  36.     p_a[n] = p_c[n] + p_d[n];  
  37.     p_b[n] = p_c[n] - p_d[n];  
  38.   }  
  39. }  
Code 5,  abfunc.cpp的實現

    說明一下code 5中用到的函數。這些函數大都以mx開頭。mxAssert是斷言,類似於C\C++中的assert。mxGetM獲得Matlab傳來的變量的行數,mxGetN獲得Matlab傳來的變量的列數。mxCreateDoubleMatrix創建一個2維的Matlab變量,形參分別用於指定變量的行數、列數、元素類型(mxREAL表示實數,mxCOMPLEX表示複數)。mxGetData用於獲得內存中數據塊的首地址。

    編譯並測試Code 5中的代碼,參見Code 6。

[plain] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mex abfunc.cpp  
  2. c = [1 2;3 4;5 6];  
  3. d = [1 1;1 1;1 1];  
  4. [a, b] = abfunc(c, d);  
Code 6, Code5的測試代碼

    Code 6的輸出結果如下:

[plain] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. a =  
  2.      2     3  
  3.      4     5  
  4.      6     7  
  5. b =  
  6.      0     1  
  7.      2     3  
  8.      4     5  



關於數據存儲的說明

   Matlab中的數據是按列存儲的。例如,a=[1,2;3,4;5,6],a的數據在內存中的存儲順序是:1、3、5、2、4、6。在C\C++中使用Matlab傳來的變量時,一定要注意數據的存儲順序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章