覃楊森,郭世偉,劉語喬
(中國飛行試驗研究院 陜西 西安710089)
Matlab混合編程方法研究
覃楊森,郭世偉,劉語喬
(中國飛行試驗研究院 陜西 西安710089)
利用Matlab函數工具箱可以提高對工程數據的分析效率。C++builder能夠便捷的設計用戶界面,并可以直接與系統底層交換數據,因此研究C++builder與Matlab的混合編程具有實際應用意義。研究如何使用matcom中間件將Matlab平臺下的M函數編譯為CPP文件,并研究實踐將M文件編譯形成動態(tài)庫,研究分析在C++builder平臺下以進程調用Matlab函數應用程序的方式??偨Y分析了Matlab混合編程方法對系統資源的使用情況。
MATLAB;混合編程;中間件;動態(tài)庫
Matlab作為應用最為廣泛的數學軟件,具有非常強大的數值計算、數據分析處理、系統分析、圖形顯示甚至符號運算的功能,已經在如圖像處理、語音處理以及控制論、系統論等各個領域得到深入應用[1]。Matlab是一個完整的數學平臺,在這個平臺上,用戶只需完成簡單編程語句就可以現實十分復雜的計算功能,大大提高了工程分析的效率。但是Matlab強大的功能只能在它所提供的平臺上才能使用,要求用戶必須在安裝Matlab環(huán)境的操作系統平臺上才能執(zhí)行*.m文件。這樣當用戶需要將Matlab下已開發(fā)成熟的復雜算法應用到高級語言開發(fā)環(huán)境下時就帶來了困難,是將現成的東西集成到高級語言開發(fā)程序中,還是用高級語言再重新實現一遍已成為眾多工程技術人員難以取舍的問題[2]。顯然,對于開發(fā)者而言,所期望的是盡可能減少工作量,最好能將Matlab下開發(fā)好的程序或者函數直接應用到高級語言開發(fā)的程序中,這就需要探討Matlab與高級語言的混合編程問題。
Matlab中間件編譯調用方式,主要借助中間件matcom對Matlab函數進行編譯運行[3]。Matcom是M文件翻譯器,提供了M文件與其他高級語言的接口,使得M文件可被編譯為脫離matlab環(huán)境獨立執(zhí)行并可調用的二進制可執(zhí)行程序[4]。在安裝中間件matcom之前,需要首先安裝C++builder開發(fā)環(huán)境,并且選擇安裝在默認的路徑下。在安裝中間件過程中,當進行到編譯器選擇時,matcom將自動檢測當前系統環(huán)境已經安裝的開發(fā)環(huán)境編譯器,在此,應該選擇C++builder。在確認了matcom可以正常運行后,即可以讀入M文件。進行編譯,生成對應的頭文件與CPP文件,將生成的這兩個文件導入到C++builder工程中,并在主程序中include中間件的頭文件,就可以實現了對matlab函數的調用[5]。其具體步驟如圖1所示。
圖1 中間件編譯步驟
在步驟二中,M文件編寫完后,將M文件保存為mywelch.m,編譯后的mywelch.cpp文件在 “….matcom45Debug”中;
在步驟三中,C++builder調用mywelch.cpp過程如下:
1)建立一個C++builder工程,在From中拖放一個button按鈕;
2)將mywelch.cpp和mywelch.h拷到上一步建立的工程文件夾中;
3)將….matcom45lib中的matlib.h和v4501b.lib拷到上一步建立的工程文件夾中;
4)單擊 C++builder Project菜單中的 Add to Project命令,將mywelch.cpp和v4501b.lib加入工程;
5)雙擊button開始編程,需要在頭文件中加入matlib.h和mywelch.h,重要程序片段如下:
注意:必須加上 initM(MATCOM_VERSION)和exitM()語句。
另外,也可以直接按照Matcom的語法,在C++builder中書寫Matlab語句,實現對matlab函數的調用,其具體步驟如上所述一致,核心程序體如下:
編譯運行后,會得到和前一種方式相同的結果。經過對比,發(fā)現中間的代碼和mywelch.cpp中產生的代碼幾乎一樣。
經過編程實踐,在脫離了matlab環(huán)境下,以上兩種方法可實現對matlab函數的調用。方法一必須安裝matcom(不過matcom只有 8.2M,相比 matlab很?。?;方法二即使在沒有安裝matcom和matlab的機子上也可實現對matlab函數的調用,但是必須按照Matcom的語法,在C++builder中書寫Matlab語句,同時在編寫C++builder程序時,需要加入matlib.h,v4501b.lib文件[6]。生成的程序如果完全在沒有安裝Matcom機子上運行,需要兩個matcom安裝時產生的dll,即ago4501.dll和v4501b.dll即可。兩種方法對比,如果剛開始使用可以先安裝matcom,在里面編譯,不易出錯,如果熟練,可以用最后一種方法,獨立于matcom編寫C++builder程序[7]。另外,VC++程序也可調用MATlab函數,也有相應的matcom-VC版本。
根據計算需要,以完成一個3D繪圖示例為范本,對該調用方式進行應用說明[8]。首先在Matlab平臺下編寫完成M文件,執(zhí)行安裝命令“mex-setup”與“mbuild-setup”,完成安裝編譯器。針對M文件執(zhí)行命令“mcc-W cpplib:libdraw3d-T link:lib Draw3D”,生成.ctf、.dll及.lib 文件。
將生成的 libdraw3d.lib,libdraw3d.ctf,libdraw3d.h,libdraw3d.dll文件復制到工程文件夾下,并通過菜單“project-》add to project”把以上4個文件同時加入到工程中[9],并在菜單“project-》options-》Directories/Conditionals” include path 添 加 入 路 徑 “C:Program FilesMATLAB71externinclude”;library path 添 加 入路 徑 “C:Program FilesMATLAB71externlib”,在compiler選項卡中將選項 “Treat enum types as ints”選中,并在 Unit1.cpp文件中添加入 #include"libdraw3d.h",核心代碼如下:
在工程代碼中加入析構類,并在頭文件中聲明__fastcall~TForm1();:
析構類的結構如下:
在Matlab平臺下,將需要使用的算法庫寫成函數形式的M文件,可以在函數體中對算法庫直接調用,也可以是嵌套調用[10]。在函數形式的M文件中定義需要使用到的參數接口,這將影響到用戶界面GUI的輸入組件設計。完成函數的參數接口定義之后,創(chuàng)建Matlab圖形用戶界面工程,根據參數接口定義的情況,對應分布輸入組件,針對組件綁定的callback屬性,與函數建立起對應關系,并由此獲取到算法中需要的計算參數[11]。如果是文件,則需要啟用文件選擇對話框交互,獲取到文件句柄,形成傳遞參數,完成算法參數的響應。接著,針對GUI工程中的M文件,啟用Matlab命令deploytool,以exe工程方式新建項目,將GUI工程編譯形成可執(zhí)行exe文件,并生成對應的說明文本[12]。在此,便可以在C++builder環(huán)境下,以進程應用程序的調用語句,即可將在軟件界面上添加入matlab的交互執(zhí)行觸發(fā)動作,具體步驟如圖2所示。
圖2 應用程序調用步驟
對于此方式的調用,需要通過單獨的共享數據區(qū)實現兩個平臺的數據操作,不可以通過全局變量定義或變量外部調用。另外,命令deploytool在Matlab2012b版本下使用更為方便,對于早期的版本,可以借鑒使用comtool命令[13]。如果需要在沒有Matlab軟件環(huán)境下使用exe程序,則需要在對M文件打包過程中,在文件包中包含入MCR (Matlab Compiler Runtime)安裝包,用于在無Matlab安裝的環(huán)境下解析形成的exe程序,以實現跨平臺的應用[14]。
由于使用了Matlab動態(tài)庫的調用方式,使得C++builder主程序在運行時就觸發(fā)了Matlab動態(tài)引擎庫的運行,此引擎庫會綁定到主程序運行時的進程中,因此,在這種情況下,由于進程資源互鎖,在主程序體內應用Application->Terminate()方法將不再能夠完成退出進程的操作[15]。則需要首先獲取到主程序句柄,進而利用進程強制中斷的方式,使得主程序的進程優(yōu)先等級提升,通過系統進程管理調度釋放掉matlab的動態(tài)引擎資源,從而也就使得主程序實現了退出操作。具體過程如圖3所示。
圖3 進程生命關系圖
Matlab有多種混合編程模式,可以和多種高級語言環(huán)境相融合使用。本文僅討論了Matlab與C++builder平臺下的兩種混合模式,在僅有使用計算函數,而不進行參數輸出調用的情況下,通過中間件matcom將m函數文件編譯形成動態(tài)鏈接庫后在高級語言平臺下進行調用,可以較為便捷方便,而且占用計算資源較小。但如果涉及到用戶交互上,則需要通過圖形用戶界面控件,傳遞和共享部分的參數與數據。由于需要同時運行兩個不同平臺的可執(zhí)行程序,因而,使用應用程序調用方式更為適合,可以在非模態(tài)窗口下進行操作,分別獨立管理占用的兩個進程ID句柄,系統資源使用較為靈活。另外,在進行混合編程過程中,首先要對Matlab版本平臺的編譯器進行分析,以確保是否能與高級語言開發(fā)環(huán)境相兼容,從而確定之間的混合方式,提高編程過程中的程序調試效率。
[1]彭煜祺.計算軟件MATLAB及其應用淺析[J].電腦知識與技術,2015(5X):204-206.
[2]左明成,武云.VC++和MATLAB混合編程的新應用[J].計算機技術與發(fā)展,2014(12):45-47.
[3]李璞,趙地.Matlab與VC++混合編程技術在信號采集中的應用[J].計算機與網絡,2013,39(12):56-58.
[4]宗節(jié)保,尹忠,成鴻飛,等.MATLAB中調用VC混合編程方法的研究與實現 [J].電子設計工程,2010,18(8):105-108.
[5]胡春曉,石巖.基于Matlab和C混合編程的火炮精度數據處理軟件實現[J]//現代電子技術,2014(21):35-37.
[6]胡哲,馬駿,趙艷雄,等.基于Python和MATLAB的CAE可視化分析平臺的設計開發(fā)[C]//全國結構工程學術會議,2015.
[7]崔芃,吳旭光,牛云,等.基于動態(tài)鏈接庫的Simulink仿真技術[J].工業(yè)儀表與自動化裝置,2014(3):44-46.
[8]冷信風,賴祖龍,熊思橋.基于 MATLAB與小波進行沉降數據處理與分析[J].測繪與空間地理信息,2014(2):180-182.
[9]胡寶剛.基于C#和MATLAB混合編程的合成頻譜儀的數據處理 [J].電子技術與軟件工程,2015(12):84-84.
[10]慕巍,王若亮,李晶娣,等.基于ActiveX引擎的VC++與Matlab混合編程及其應用[J].電子設計工程,2010,18(9):40-42.
[11]陳建,張勝良,李鑫.MATLAB GUIDE程序設計參數在內部函數間及窗口間傳遞方式研究[J].軟件導刊,2015,14(9):12-16.
[12]吳志偉,趙祚喜,黃培奎,等.基于Matlab的機器人避障仿真軟件設計[J].計算機應用,2015(S1):226-228.
[13]齊惠娟,李敏.基于MATLAB GUI實現隨機信號的分析與處理[J].電子設計工程,2011,19(12):11-14.
[14]李雯.Matlab接口技術應用研究[J].電子測試,2016(7):12,62.
[15]李凱,王勁松.Visual C#與Matlab混合編程原理及其在數據圖形化中的應用 [J].數字技術與應用,2014(9):55-56.
Research on Matlab Hybrid programming method
QIN Yang-sen,GUO Shi-wei,LIU Yu-qiao
(Chinese Flight Test Establishment,Xi'an 710089,China)
The analysis efficiency of engineering data can be improved by using Matlab function toolbox.C++builder can easily design the user interface,and can exchange data directly with the bottom layer of the system,so it is meaningful to study the mixed programming of C++builder and Matlab.Study how to use the Matlab middleware to compile the M function on the Matcom platform to the CPP file,and study the practice of compiling M files into a dynamic library,research and analysis in the C++builder platform to call the process of Matlab function application.The use of system resources by Matlab mixed programming method is summarized and analyzed.
MATLAB; mixed programming;middleware;dynamic library
TN99
A
1674-6236(2017)17-0107-04
2016-07-14稿件編號:201607108
國防基礎科研項目(A0520132031)
覃楊森(1986—),男,廣西柳州人,碩士,工程師。研究方向:飛行試驗測試數據處理技術。