Matcom是mathTools公司推出的最早的Matlab到C++的編譯器。後來,由於Mathtools被Matlab公司收購,Mtacom對Matlab 5.3以後的版本就沒有推出新的版本。相比Matlab內建的編譯器Compiler,用Matcom轉化代碼要簡單和方便得多;且對於採用C++的工程和研究人員來說Matcom的C++矩陣庫(Matrix Lib)依然有非常大的利用價值。 通過Matcom串連M函數這類指令碼語言或者進階演算法語言有三種辦法:—是將M檔案編譯成C++代碼,然後在C++工程中插入這些代碼,最後編譯成為獨立的可執行程式;二是直接在C++程式中使用Matcom提供的Matrix<lib>,方法與一相似,但常用。最後一種是利用MIDEVA直接產生EXE檔案,然後在VC中通過shell調用,方法簡單,但通用性差,僅適用於VC中調用Matlab實現圖形顯示的場合。 Mideva軟體平台本身的功能相當強大,提供近千個Matlab的準系統函數,通過必要的設定,就可以直接實現與C++的混合編程,而不必再依賴Matlab;同時,Mediva還提供編譯轉換功能,能夠將Matlab函數或編寫的Matlab程式轉換為C++形式的DLL,從而實現脫離Matlab環境對Matlab函數和過程的有效調用,這樣就有可能實現對Matlab強大的工具箱函數的利用。 Mideva的缺點是C++與Matlab混合編寫的應用軟體必須攜帶必要的DLL,從而增大了軟體的體積(約4M),同時也不能對所有的Matlab函數提供支援,例如採用類庫進行設計的部分函數。 本節將以VC++6.0和Matcom為例,1,詳細介紹如何利用Matcom進行VC++與Matlab的聯合編程(即一);2 ,介紹一下在VC++中怎樣使用Matcom C++矩陣庫(即二)。 1. 目前,Matcom的最高版本為4.5。首先安裝Matcom 4.5,如 : 安裝Matcom前要已求安裝VC++6.0。在安裝過程中出現選擇編譯器對話方塊,選擇”是” 如: 出現選擇是否安裝了Matlab時,如果本機上安裝的是Matlab 5.3版本,可以選擇“是(Y)”確認,因為Matcom4.5不支援Matlab 6.1以上的版本。其他選項採用預設設定。Matcom可以獨立於Matlab運行,但需要外部的C++編譯器,指定Matlab的位置是為了讓編譯檔案中需要的一些系統函數找到路徑用的。 安裝完成後,在“<Matcom 根目錄>lib”下,可以找到使用MatcomC++矩陣庫(Matrix Lib)的標頭檔matlib.h和v4501v.lib檔案,在Windows作業系統目錄的system32目錄下,可以找到使用MatcomC++矩陣庫的動態連結程式庫檔案v4501v.dll。啟動介面MIDEVA,如。MIDEVA整合式開發環境包括命令列視窗、變數列表視窗、命令列表視窗和編譯連結資訊視窗等幾部分,並有詳細的協助文檔。 Matcom命令輸入方法與Matlab相同。如果安裝在中文版作業系統時,輸入命令前加一空格,否則顯示為亂碼。 下面詳細介紹如何將m檔案編譯後放入VC++中。 啟動MIDEVA ,File->New,建立如下huatu.m檔案。 m檔案儲存的預設位置為:matcom安裝目錄matcom45,產生的C++檔案儲存的預設位置為matcom安裝目錄matcom45Debug,本例matcom安裝目錄為C盤 即 C:matcom45Debug,在該目錄下將會產生huatu.h、huatu.cpp、huatu.r 、huatu.obj檔案。 在VC++中用MFC Wizard(exe)建立一個基於對話方塊名為Example的工程。在面板上添加一個ID為IDC_BUTTON1按扭。 C:matcom45Debug目錄下的huatu.cpp檔案的內容拷貝到void CExamleDlg::OnButton1()如下, void CExampleDoc::OnButton1() { dMm(x); dMm(y); #line 1 "c:/matcom45/huatu.m" call_stack_begin; #line 1 "c:/matcom45/huatu.m" _ x = colon(-2.0,0.1,2.0); #line 2 "c:/matcom45/huatu.m" _ y = power(x,2.0); #line 3 "c:/matcom45/huatu.m" _ display( plot((CL(x),y)) ); call_stack_end } 將C:matcom45lib下的matlib.h 和v4501v檔案和C:matcom45debug下的huatu1.h檔案拷貝到工程Example目錄下,然後在VC中將庫檔案和標頭檔加入到工程中:工程->添加工程->Files,選擇剛剛拷貝到Example目錄下的matlib.h 、v4501v和huatu1.h檔案 五,在ExamleDlg.cpp中加入如下代碼: #include "matlib.h" #include "huatu.h" 在void CExamleDlg::OnButton1()中分別添加一個初始化類庫調用函數”initM(MATCOM_VERSION)”和一個結束類庫調用函數”exitM()”如下。 void CExampleDoc::OnButton1() { initM(MATCOM_VERSION) dMm(x); dMm(y); #line 1 "c:/matcom45/huatu.m" call_stack_begin; #line 1 "c:/matcom45/huatu.m" _ x = colon(-2.0,0.1,2.0); #line 2 "c:/matcom45/huatu.m" _ y = power(x,2.0); #line 3 "c:/matcom45/huatu.m" _ display( plot((CL(x),y)) ); call_stack_end exitM() } 運行程式,點擊畫圖按扭得圖: Matcom C++ 矩陣庫的初始化和釋放是成對出現的,在初始化時,調用函數initM(Matcom_VERSION),在需要釋放的時候,調用函數exitM()即可。Matcom C++ 矩陣庫的初始化需要一定的時間,為了加快程式的執行速度,應盡量減少Matcom C++ 矩陣庫的初始化的次數。所以開發人員應仔細考慮Matcom C++ 矩陣庫生存周期的長度,在Matcom C++ 矩陣庫生存周期的開始初始化C++庫,在生存周期結束的時候,釋放 C++庫。這樣雖然會佔用一定的記憶體,但是會提高程式啟動並執行速度。 Matcom不但可以產生C++檔案,而且還可以產生exe檔案和dll檔案。: 2.下面通過一個例子來說明Matcom C++ 矩陣庫在Visual C++ 6.0中使用的過程: 在Visual C++ 6.0中,建立一個Win32 Console工程,如。實際上在任何類型的 C++工程中都可以使用Matrix<lib>,為了簡單我們以控制台程式為例。 二.設定工程,開啟Project|Setting的link標籤,作如下修改見: 開啟C/C++標籤,作如下修改見: 加入標頭檔matlib.h,看是否成功?不成功檢查設定! 在Example.cpp中輸入如下程式 #include "stdafx.h" #include "stdio.h" #include "matlib.h" int main(int argc, char* argv[]) { initM(Matcom_VERSION); Mm a; a=rand(3,3); display(a); exitM(); return 0; } 輸出結果: ans (3x3)=9 double elements real (72 bytes)= 0.9501 0.4860 0.4565 0.2311 0.8913 0.0185 0.6068 0.7621 0.8214 在這說明一下,Matcom C++矩陣庫採用物件導向的設計風格,矩陣資料和操作都封裝在類Mm中。當需要建立矩陣的時候,只要聲明一個Mm對象執行個體即可。如:Mm a; 關於Matlab所產生的COM組件,還有以下幾個在實踐中較為有用的說明: 1. 對於用於產生COM的任何一個Matlab函數,在COM組件中即為一個COM的方法,而Matlab函數中的全域變數(global)則為COM組件的一個屬性。這一點對於神經網路編程中頗為有用,比如說,在ANN訓練結束後,做模擬(simulate)時,我們需要調用Matlab產生的COM組件,但是,顯然我們不能每調用一次COM就讀一次ANN的配置(如權重、偏置等項目的值),也不能在VC中出現Matlab的結構體或者類。在這種情況下,我們就可以專門做一個Matlab函數,使用該函數調入ANN設定檔(一般為.mat檔案)。而把ANN的配置量聲明為全域變數,則可以在模擬函數中直接使用該變數。就像以下的樣本: function y = sim_ann(x) global net y = sim(net, x); function LoadAnnParam global net % AnnMat.mat檔案中儲存了net變數 load AnnMat net 在VC中調用時,設COM對象為comObj,則有以下調用方式: comObj.LoadAnnParam(); //載入ANN參數 for(int I = 0; I < n; I++) comObj.sim_ann(1, x, y); //多次模擬ANN 2. 在Matlab中可以自訂資料類型,也就是VC中的類,但是這在產生COM組件時,會出現在load新類的對象時Matlab不認識該類型。這種情況下,我們可以在load該類以前,先初始化一個同名的該類型的對象。比如我們有NewClass這種新類,要load進來一個該類型的名字為NewObj的對象,對象的初始化函數為InitNewClass,則可以: NewObj = InitNewClass; Load mat_file NewObj; 3. 另外,在編程過程中曾遇到過這種情況,在產生的COM介面中如果輸出變數為結構體時,有時會出現莫名其妙的峰鳴器常鳴的效果。這種情況經過多方尋找無法找到原因,如果各位讀者在使用中出現類似情況,可以從這個方面考慮問題的解決方案。 |