摘 要: 研究了基于MATCOM的MATLAB與VC混合編程技術,,提出了一種簡便的設置MATCOM環(huán)境的方法,,介紹了MATCOM提供的一個方便調試工具——矩陣查看器及其具體使用方法,。結合實例,,詳細介紹了基于MATCOM的混合編程的實現(xiàn)途徑,對擴展MATCOM的功能提出了一種獨到的解決辦法,。
關鍵詞: MATCOM,;MATLAB;VC,;混合編程
MATLAB是MathWorks公司推出的數(shù)學軟件,,它將數(shù)值分析、矩陣計算,、信號處理,、數(shù)據(jù)采集和圖形顯示結合在一起,包含大量高度集成的函數(shù)可供調用?,F(xiàn)在,,MATLAB幾乎在各個領域都得到了廣泛的應用,也取得了巨大的成功,,被稱為第四代編程語言,。
但是MATLAB使用的是解釋性語言,這大大限制了它的執(zhí)行速度,,而且用MATLAB開發(fā)的程序只局限于MATLAB運行環(huán)境而不能作為商業(yè)軟件,。
VC作為Windows平臺下主要的應用程序開發(fā)環(huán)境之一,能方便實現(xiàn)軟件開發(fā),,但在工程計算及可視化方面,,與MATLAB相比編程顯得復雜很多,因此,,將VC與MATLAB混合編程,,必將為軟件開發(fā)帶來便利。
本文介紹基于MATCOM的混合編程方法,。示例中用到的軟件為MATLAB R2009A和VC 6.0,。為了便于敘述,用VC6.0新建一個基于對話框的程序TestMatcom,。
1 MATCOM簡介
MathTools公司有一系列的產品,,包括MIDEVA、MATCOM,、Visual MATCOM,、Matrix
2 MATCOM的安裝與配置
MATCOM的安裝與普通Windows程序的安裝過程類似,可參考文獻[1],、[2]所述,。成功安裝后,,在目錄C:\matcom45\lib下可找到matlib.h及v4501v.lib這2個文件,,在Windows操作系統(tǒng)的system32目錄下可找到v4501v.dll和ago4501.dll這2個文件。將這4個文件拷貝到TestMatcom工程中再做如下配置即可:
(1)在VC的FileView標簽中的Resource Files目錄上點擊右鍵->Add Files to Folder->文件類型選擇“Library Files(.lib)”->選中v4501v.lib ->點擊“OK”即添加成功,。
(2)在需要使用MATCOM函數(shù)的文件中添加#include "matlib.h",。本文示例在TestMatcomDlg.cpp中添加。
(3)在使用MATCOM的函數(shù)之前,,添加初始化語句:initM(MATCOM_VERSION),。本文示例在void CTestMatcomDlg::OnPaint()函數(shù)中添加。
(4)在使用MATCOM的函數(shù)之后,,添加釋放資源語句:exitM(),。本文示例也在void CTestMatcomDlg::OnPaint()函數(shù)中添加。
為了使Visual MATCOM可用,,也需做相應的配置,,參考文獻[1]、[3]介紹了配置的過程,,本文從略,。
3 巧用矩陣查看器
安裝完Visual MATCOM之后可以看到Visual MATCOM工具欄中有個眼鏡按鈕,這個就是矩陣查看器,。在調試模式下可以通過它查看MATCOM矩陣的值,,這對VC程序調試是非常方便的。在VC中,,指針變量和數(shù)組尤其是二維及以上的指針變量和數(shù)組的元素值是不方便查看的,。有了這個工具,就可以將需要查看的指針變量或數(shù)組的值傳遞給MATCOM矩陣,,然后在矩陣查看器中查看[3],。具體的查看方法是:在相應位置設置斷點,當VC程序運行到斷點停下后,點擊矩陣查看器按鈕,,然后在矩陣名對話框里輸入矩陣名,,并點擊Reload按鈕,矩陣的內容即可顯示出來,。另外,,為了使得矩陣查看器能在程序中起作用,需要在VC程序中添加:unsigned int mlibpr=mt_set_MT(0),。
示例:
/*定義1個二維數(shù)組*/
double a[2][3]={1,,2,3,,4,,5,6},;
/*定義1個Mm 矩陣,,
并初始化為2行3列,元素都為0*/
Mm ma=zeros(2,,3),;
/*將數(shù)組元素復制到ma中*/
memcpy((char*)ma.addr( ),(char*)a,,6*sizeof(double)),;
4 混合編程的實現(xiàn)
混合編程有不同的實現(xiàn)途徑,本文將其分為二大類,。
4.1 將M文件轉化為C++代碼
M文件可分為腳本文件和函數(shù)文件兩大類,。這兩者的混合編程實現(xiàn)步驟略有不同。現(xiàn)以2個示例說明,。
例1:
%wires.m
n=1000,;
t=inspace(0,2*pi,,n),;
x=sin(t).*sin(2*t).*sin(3*t);
y=cos(5*t).*cos(7*t).*cos(11*t),;
plot(x,, y);
雙擊桌面上的MIDEVA圖標打開MIDEVA,,然后在MIDEVA菜單欄中選File->Compile to exe,,在彈出的Go command對話框中通過瀏覽選擇wires.m這個文件,然后點擊OK.轉化成功后可以在C:\matcom45\Debug下找到wires.cpp這個文件,。打開這個文件,,可以看到內容為(刪去不需要的代碼,,注釋為筆者添加,欲全面了解M文件與其對應的CPP文件的關系,,可以參考文獻[2]):
//Mm為處理矩陣的類
Mm n,; Mm t; Mm x,; Mm y,;
n=1000.0;
t=linspace(0.0,,2.0*pi,,n);
x=times(times(sin(t),,sin(2.0*t)),,sin(3.0*t));
/*MATLAB的點乘操作在VC里面通過times函數(shù)實現(xiàn),。*/
y=times(times(cos(5.0*t),,cos(7.0*t)),cos(11.0*t)),;
plot((CL(x),,y));/*輸入?yún)?shù)個數(shù)不定時,,需用CL函數(shù)。注意y不用加CL()*/
可以看出,,經MATCOM轉化后的C++代碼和M代碼幾乎句句對應,,可讀性強。將以上內容拷貝到void CTestMatcomDlg::OnPaint()函數(shù)中,,編譯運行即可得到所需的結果,。
例2:
%CreateMagic.m
function result=CreateMagic(n)
result=magic(n);
用MATCOM成功轉化后可以在Debug目錄下找到CreateMagic.cpp和CreateMagic.h這2個文件,。將其添加進TestMatcom工程中并在TestMatcomDlg.cpp中添加1句:#include“CreateMagic.h”同時在消息響應函數(shù)中添加代碼:“Mm a=5,; Mm b=CreateMagic(a);”可驗證b為5×5的魔方陣,。若編譯不通過 ,,可嘗試在CreateMagic.cpp文件中添加#include "stdafx.h"。
4.2 將M文件轉化為DLL
出于代碼保密等原因,,有時需要將M文件轉化為DLL以供其他程序調用,,這時可以利用MATCOM的Compile to dll功能來實現(xiàn)。
示例:
%Exchange2.m
function[c,,d]=Exchange2(a,,b)
c=b;
d=a;
通過File->Compile to dll將該M文件轉化為dll,,在Debug目錄下可找到Exchange2.lib和Exchange2.dll這2個文件,,將其放入TestMatcom工程目錄下并在TestMatcomDlg.cpp中添加以下代碼:
#pragma comment(lib, "Exchange2.lib")
extern "C" int DLLX_stdcall Exchange2_v(char* emsg,, int nlhs,, Mm* plhs[ ], int nrhs,, Mm* prhs[ ]),;
MATCOM將M文件里面的函數(shù)Exchange2轉化成了Exchange2_v函數(shù),該函數(shù)的第1個參數(shù)emsg用于傳遞1個消息字符串,,可賦值為NULL,;第2個參數(shù)nlhs是Exchange2函數(shù)定義的輸出參數(shù)的個數(shù);第3個參數(shù)plhs[]是指向輸出參數(shù)的指針數(shù)組,;第4個參數(shù)nrhs是Exchange2函數(shù)中定義的輸入?yún)?shù)的個數(shù),;第5個參數(shù)prhs[ ]是指向輸入?yún)?shù)的指針數(shù)組。
在消息響應函數(shù)中添加如下代碼:
Mm a,, b,, c, d,;
a=zeros(1,,3);
b=ones(1,,3),;
b.r(1,2)=100,; /*將矩陣b的第1行第2列元素賦值為100 */
Mm* Input[2]={&a,,&b};
Mm* Output[2],; //不用為其分配空間
//調用dll函數(shù)
Exchange2_v(NULL,, 2, Output,, 2,,Input);
//查看第1個輸出參數(shù)的結果
Mm lookOutput1=*Output[0],;
//查看第2個輸出參數(shù)的結果
Mm lookOutput2=*Output[1],;
即實現(xiàn)了調用dll里的Exchange2_v函數(shù)。
MATLAB與C++混合編程的方法有8種之多,。但是基于MATCOM的混合編程方法簡便易行,,生成的代碼可讀性很好,,筆者認為是實現(xiàn)MATLAB與VC混合編程的最優(yōu)途徑。在實際工程應用當中,,經常會調用到很多的MATLAB工具箱函數(shù),,而對于MATLAB 5.3版本以后新增的函數(shù)或者MATLAB工具箱函數(shù),MATCOM并沒有提供相對應的函數(shù),。這時可以采用的解決辦法是:將用到的函數(shù)對應的M文件(可從MATLAB安裝目錄中獲得)拷貝到與待轉化的M文件同一個目錄下,,MATCOM會自動進行關聯(lián)分析并轉化。轉化完成后只需將生成的頭文件和源文件一起放到VC工程中就可以了,。筆者在車牌識別系統(tǒng)中采用這種方法有效縮短了系統(tǒng)開發(fā)的周期和效率,。
參考文獻
[1] MathTools Ltd. MIDEVA, MATCOM & visual MATCOM installation guide (V4.5 release).1999.
[2] 劉維.精通Matlab與C++混合程序設計[M].(第2版). 北京:北京航空航天大學出版社,,2008:257-315.
[3] 羅蛟龍,,張鵬,張維競.Visual C++下強大的科學運算函數(shù)庫—MATCOM之Matrix
26(12):152-154.
[4] MathTools Ltd. Matrix