亓雪冬 李霞
摘 要:?研究了MATLAB與C 混合編程方法。首先討論了MATLAB與C#混合編程架構(gòu),分析了架構(gòu)各關(guān)鍵部分的作用和調(diào)用關(guān)系,接下來(lái)研究了MATLAB與C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換方法、MATLAB函數(shù)對(duì)應(yīng)的.Net程序接口形式等混合編程的關(guān)鍵技術(shù),最后通過(guò)實(shí)際項(xiàng)目設(shè)計(jì)了混合編程流程,編制了相關(guān)程序,驗(yàn)證了MATLAB和C#混合編程的可行性。實(shí)踐表明,MATLAB和C#兩種語(yǔ)言的集成,能夠充分發(fā)揮各自的優(yōu)勢(shì),拓展解決問(wèn)題的空間,提高系統(tǒng)設(shè)計(jì)和開(kāi)發(fā)效率。
關(guān)鍵詞:?MATLAB; C#; .Net; 混合編程
中圖分類(lèi)號(hào): TP 393? ? ? 文獻(xiàn)標(biāo)志碼: A
Research on Mixed Programming Method of MATLAB and C#
Qi Xuedong1, LI xia2
(1. Information Construction Department; 2. College of Information and Control Engineering,?China University of Petroleum (East China), Qingdao, Shandong? 266580, China)
Abstract:
Mixed programming of MATLAB and C# is studied. First, the mixed programming architecture of MATLAB and C# is discussed, and the role and calling relationship of each key part of the architecture are analyzed. Next, key techniques of mixed programming are studied such as MATLAB and C# data type conversion method and different .Net interface API forms generated by MATLAB functions. Finally, the mixed programming flow is designed and the feasibility of mixed programming of MATLAB and C# is verified. Practice shows that the integration of MATLAB and C# can give full use to their respective advantages, expand the space for solving problems, and improve system design and development efficiency.
Key words:
MATLAB; C#; .Net; mixed programming
0 引言
MATLAB是美國(guó)MathWorks公司的科學(xué)計(jì)算軟件,以矩陣作為基本數(shù)據(jù)組織單元,集成了數(shù)據(jù)分析、無(wú)線通信、深度學(xué)習(xí)、信號(hào)處理、控制系統(tǒng)、金融建模和計(jì)算機(jī)視覺(jué)等眾多科學(xué)和工程領(lǐng)域大量?jī)?yōu)秀算法,在科學(xué)研究和工程設(shè)計(jì)等領(lǐng)域應(yīng)用廣泛。C#是微軟公司發(fā)布的一種面向?qū)ο蟮?、運(yùn)行于.NET Framework和.NET Core之上的高級(jí)程序設(shè)計(jì)語(yǔ)言。C#以其較高的運(yùn)行效率、強(qiáng)大的表示能力、優(yōu)雅的語(yǔ)法風(fēng)格、創(chuàng)新的語(yǔ)言特性和便捷的面向組件編程等特點(diǎn)成為.NET開(kāi)發(fā)的重要編程語(yǔ)言。
對(duì)比這兩種編程語(yǔ)言,其側(cè)重的領(lǐng)域有所不同。C#更偏重于傳統(tǒng)桌面和網(wǎng)絡(luò)編程領(lǐng)域,而MATLAB更偏重于數(shù)據(jù)分析和計(jì)算領(lǐng)域[1-2]。為了能夠?qū)⑦@兩種編程語(yǔ)言有機(jī)融合,充分發(fā)揮各自的優(yōu)勢(shì),本文從混合編程架構(gòu)、混合編程數(shù)據(jù)類(lèi)型轉(zhuǎn)換、混合編程調(diào)用接口等幾個(gè)方面研究了MATLAB與C#之間混合編程的方法。
1 MATLAB與C#混合編程架構(gòu)
MATLAB與C#混合編程重要概念、關(guān)鍵部分以及關(guān)鍵部分之間的聯(lián)系如圖1所示。
圖中fun1.m~fun3.m為MATLAB的M函數(shù),僅能夠運(yùn)行在MATLAB環(huán)境中,需使用MATLAB Compiler SDK中的庫(kù)編譯器(Library Comiler)將M函數(shù)轉(zhuǎn)換為.Net組件匯編[3-5],才能被C#調(diào)用。轉(zhuǎn)換過(guò)程中,可以根據(jù)業(yè)務(wù)需求和軟件設(shè)計(jì)規(guī)則將這些M函數(shù)邏輯劃分到.Net組件的不同類(lèi)中。如圖1中,.Net組件名為MyComp,其下包含兩個(gè)類(lèi)ClassA和ClassB,ClassA中包含fun1和fun3,ClassB包含fun2。
ClassA和ClassB中的fun1~fun3方法僅為對(duì)M函數(shù)的.Net接口,M函數(shù)的實(shí)際原代碼被加密后存儲(chǔ)在MyComp組件的資源區(qū)域中,名為MyComp.ctf。MyComp組件初始化時(shí)將MyComp.ctf發(fā)送至MATLAB運(yùn)行時(shí),初始化MATLAB運(yùn)行環(huán)境;MyComp組件收到用戶.Net調(diào)用請(qǐng)求時(shí),首先將MyComp.ctf發(fā)送至MATLAB運(yùn)行時(shí),初始化MATLAB運(yùn)行環(huán)境;然后將.Net調(diào)用轉(zhuǎn)化為MATLAB調(diào)用轉(zhuǎn)發(fā)至MATLAB運(yùn)行時(shí)進(jìn)行實(shí)際處理;調(diào)用結(jié)束后再將返回結(jié)果轉(zhuǎn)發(fā)至用戶程序。
可見(jiàn),MATLAB函數(shù)轉(zhuǎn)換后的.Net組件在實(shí)際執(zhí)行過(guò)程中必須依賴MATLAB運(yùn)行時(shí)。MATLAB運(yùn)行時(shí)是一套獨(dú)立的共享庫(kù),為編譯后的MATLAB程序執(zhí)行提供支持。對(duì)比MATLAB,MATLAB運(yùn)行時(shí)體積更小,可獨(dú)立分發(fā)和安裝,且可免費(fèi)使用。
此外,在混合編程過(guò)程中,還需考慮MATLAB與C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換以及MATLAB函數(shù)對(duì)應(yīng)的.Net接口API形式等問(wèn)題,這些問(wèn)題在本文后續(xù)部分詳細(xì)討論。
2 MATLAB與C#混合編程關(guān)鍵技術(shù)
2.1 MATLAB與C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換
MATLAB數(shù)據(jù)類(lèi)型與.Net數(shù)據(jù)類(lèi)型不兼容,為了使得在調(diào)用過(guò)程中能夠正確傳遞數(shù)據(jù),MATLAB Compiler SDK提供了.Net形式的MWArray數(shù)據(jù)轉(zhuǎn)換類(lèi)庫(kù)。MWArray類(lèi)及其子類(lèi)一方面是對(duì)MATLAB原始數(shù)據(jù)類(lèi)型的封裝,另一方面其構(gòu)造函數(shù)、方法、運(yùn)算符重載等實(shí)現(xiàn)了與C#常見(jiàn)數(shù)據(jù)類(lèi)型的轉(zhuǎn)換。因此,MWArray類(lèi)庫(kù)左右銜接MATLAB與C#數(shù)據(jù)類(lèi)型,實(shí)現(xiàn)了這兩種數(shù)據(jù)類(lèi)型的轉(zhuǎn)換。
MWArray類(lèi)庫(kù)層次結(jié)構(gòu),如圖2所示[6]。
其中MWArray為整個(gè)類(lèi)庫(kù)的抽象基類(lèi),代表了MATLAB數(shù)據(jù)類(lèi)型的抽象;MWObjectArray、MWCharArray、MWCellArray和MWStructArray為MWArray的子類(lèi),分別代表Matlab對(duì)象、字符、元胞和結(jié)構(gòu)體數(shù)組;MWIndexArray為MWArray的抽象子類(lèi),代表了MATLAB可索引的數(shù)據(jù)類(lèi)型的抽象;MWNumbericArray和MWLogicalArray為MWIndexArray的子類(lèi),代表Matlab的numberic和logical數(shù)組類(lèi)型。
MWArray類(lèi)庫(kù)可以與C#簡(jiǎn)單變量、數(shù)組變量進(jìn)行轉(zhuǎn)換。例如x、y、z分別為double變量、double[ ]一維數(shù)組和double[,]二維數(shù)組,并均已初始化數(shù)據(jù);mwn為MWNumbericArray類(lèi)型實(shí)例,則它們之間的轉(zhuǎn)換如表1所示。
表1中,可直接將double變量或double[ ]一維數(shù)組隱式轉(zhuǎn)變?yōu)镸WNumbericArray類(lèi)型(編號(hào)1、3),通過(guò)MWNumbericArray的構(gòu)造函數(shù)可將double[,]二維數(shù)組轉(zhuǎn)換為MWNumbericArray類(lèi)型(編號(hào)5);反之,MWNumbericArray類(lèi)型可通過(guò)顯示類(lèi)型轉(zhuǎn)換轉(zhuǎn)變?yōu)閐ouble變量(編號(hào)2),通過(guò)ToVector和ToArray方法轉(zhuǎn)變?yōu)閐ouble[ ]一維數(shù)組和double[ , ]二維數(shù)組(編號(hào)4、6)。
2.2 MATLAB函數(shù)對(duì)應(yīng).Net接口API
MATLAB中的函數(shù)在轉(zhuǎn)變?yōu)?Net組件匯編時(shí),每個(gè)函數(shù)均會(huì)生成3種不同形式的.Net方法,分別是單輸出形式(single output)、標(biāo)準(zhǔn)形式(standard)和串接形式(feval)[7]。例如某個(gè)MATLAB函數(shù)的原型為:
funtion [Out1, ... , OutN] = foo(In1, ... , InN).
則轉(zhuǎn)變后的3種.Net方法原型為:
1) 單輸出形式(single output)
public MWArray foo(MWArray In1, ... , MWArray InN);
2) 標(biāo)準(zhǔn)形式(standard)
public MWArray[ ] foo(int numArgsOut, MWArray In1, ... , MWArray InN);
3) 串接形式(feval)
public void foo(int numArgsOut, ref MWArray[ ] ArgsOut, MWArray[ ] ArgsIn)。
這里,單輸出形式返回值為MWArray類(lèi)型,適合僅有1個(gè)返回值的情況;標(biāo)準(zhǔn)形式返回值為MWArray類(lèi)型的數(shù)組,適合具有多個(gè)返回值的情況,此外需通過(guò)第1個(gè)參數(shù)numArgsOut指定返回?cái)?shù)組元素的個(gè)數(shù);串接形式與標(biāo)準(zhǔn)形式類(lèi)似,區(qū)別為不通過(guò)函數(shù)返回值而是通過(guò)按引用傳遞參數(shù)的形式從參數(shù)中返回?cái)?shù)據(jù)。
3 MATLAB與C#混合編程應(yīng)用
3.1 應(yīng)用案例
在筆者實(shí)際項(xiàng)目中,需定時(shí)通過(guò)安裝在水底管道表面的監(jiān)控傳感器采集管道中的聲波信號(hào),計(jì)算聲波的功率譜密度,進(jìn)而通過(guò)功率譜密度分析判斷管道是否有裂紋及其破損程度。設(shè)計(jì)方案使用C#程序連接監(jiān)控傳感器獲取原始聲波信號(hào),而后將聲波信號(hào)傳遞至自行編寫(xiě)的MATLAB函數(shù),函數(shù)內(nèi)部使用MATLAB的頻譜分析函數(shù)計(jì)算聲波信號(hào)的功率譜密度。此過(guò)程中涉及MATLAB與C#的混合編程。
3.2 混合編程流程及實(shí)現(xiàn)
核心算法的混合編程流程主要分為以下4個(gè)步驟:
1) 在MATLAB中編寫(xiě)計(jì)算功率譜密度的函數(shù)ComputeFFT,參數(shù)data為按時(shí)間采集的信號(hào)向量,interval為采集時(shí)間間隔,返回頻率freq和功率譜密度powerSpect兩個(gè)向量。
function [freq, powerSpect] = ComputeFFT(data, interval)
fftData = fft(data);
N = length(fftData)
freq = (0:N-1)/(N*interval);
powerSpect = abs(fftData)/(sqrt(N));
2) 通過(guò)MATLAB Compiler SDK將MATLAB函數(shù)ComputeFFT轉(zhuǎn)變?yōu)?Net組件,組件名和命名空間為SpectraComp,類(lèi)名為SignalAnalyzer,方法名為ComputeFFT,3種重載形式分別為:
public MWArray ComputeFFT (MWArray data, MWArray interval)
public MWArray[ ] ComputeFFT (int numArgsOut, MWArray data, MWArray interval)
public void ComputeFFT (int numArgsOut, ref MWArray[ ] ArgsOut, MWArray[ ] ArgsIn)
3) 在C#程序中引用基礎(chǔ)組件MWArray.dll和上述步驟生成的組件SpectraComp.dll,并啟用相關(guān)命名空間:
using MathWorks.MATLAB.NET.Arrays;
using SpectraComp;
4) 在C#中調(diào)用SpectraComp組件的ComputeFFT方法計(jì)算功率譜密度。這里采用標(biāo)準(zhǔn)API形式,第1個(gè)參數(shù)為返回值個(gè)數(shù),第2、3參數(shù)為聲波信號(hào)及采樣時(shí)間間隔,按照MWArray類(lèi)型轉(zhuǎn)換規(guī)則,后兩個(gè)參數(shù)會(huì)被自動(dòng)轉(zhuǎn)變?yōu)镸WArray類(lèi)型。返回值argsOut為MWArray[]數(shù)組,包含2個(gè)元素,argsOut[0]表示頻率向量,argsOut[1]表示功率譜向量,最后使用MWArray的ToVector方法將上述兩個(gè)向量轉(zhuǎn)變?yōu)镃#一維數(shù)組
const int N = 1024; #每次采集數(shù)據(jù)個(gè)數(shù)為1024
const interval = 0.001; #數(shù)據(jù)點(diǎn)間隔為0.001秒
#數(shù)組data用于存儲(chǔ)聲波信號(hào)
double[ ] data = new data[N];
……
#計(jì)算功率譜密度
SignalAnalyzer signalAnalyzer= new SignalAnalyzer();
MWArray[] argsOut= signalAnalyzer.Computefft(2, data, interval);
double[] freq = argsOut[0].ToVector(MWArrayComponent.Real);
double[] powerSpect = argsOut[1].ToVector(MWArrayComponent.Real);
……
某次采集的時(shí)域聲波信號(hào)和對(duì)應(yīng)計(jì)算的功率譜密度,繪制圖形如圖3所示。
4 總結(jié)
MATLAB作為重要的數(shù)值計(jì)算軟件,包含大量?jī)?yōu)秀算法庫(kù),廣泛應(yīng)用于科學(xué)研究和工程設(shè)計(jì)等領(lǐng)域。MATLAB Compiler SDK作為MATLAB組件,能夠?qū)ATLAB函數(shù)庫(kù)轉(zhuǎn)變?yōu)?Net組件匯編庫(kù),簡(jiǎn)化了MATLAB程序與C#程序之間的混合編程方案。本文研究了MATLAB與C#混合編程的宏觀架構(gòu)以及關(guān)鍵技術(shù),設(shè)計(jì)了混合編程流程,編制了相關(guān)程序。實(shí)踐表明,MATLAB和C#兩種語(yǔ)言的集成,能夠充分發(fā)揮各自的優(yōu)勢(shì),拓展解決問(wèn)題的空間,提高系統(tǒng)設(shè)計(jì)和開(kāi)發(fā)效率。
參考文獻(xiàn)
[1]
王文斌,剡昌鋒,劉朝陽(yáng),等.MATLAB繪圖窗嵌入.NET項(xiàng)目混合編程[J].計(jì)算機(jī)工程與設(shè)計(jì),2015,36(12):3413-3417.
[2] 鄭建波,于生寶,蘇發(fā),等.C#與Matlab混合編程的CSAMT靜態(tài)校正軟件設(shè)計(jì)[J].實(shí)驗(yàn)室研究與探索,2016,35(7):113-116.
[3] 陳柳松,楊利,張宇,等.基于.NET程序集的C#與Matlab混合編程技術(shù)及應(yīng)用[J].控制與信息技術(shù),2018(2):44-46.
[4] 劉亞,王靜,田新誠(chéng).基于C#和Matlab混合編程的軸承故障診斷系統(tǒng)[J].計(jì)算機(jī)應(yīng)用,2018,38(S2):236-238.
[5] Yu Zhang, Jian-Ping An, Pan Chen. Research of Hybrid Programming with C#.net and Matlab[J]. Physics Procedia,2012(24):1677-1681.
[6] mathworks. Data Conversion Between .NET and MATLAB [EB/OL]. [2019-11-10]. https://ww2.mathworks.cn/help/compiler_sdk/dotnet/data-conversion-between-net-and-matlab.html.
[7] mathworks. Data Conversion Classes and MATLAB Compiler SDK Interface [EB/OL]. [2019-11-10]. ttps://ww2.mathworks.cn/help/compiler_sdk/dotnet/overview-of-data-conversion-classes.html.
(收稿日期: 2019.08.30)