亓雪冬 李霞



摘 要:?研究了MATLAB與C 混合編程方法。首先討論了MATLAB與C#混合編程架構,分析了架構各關鍵部分的作用和調用關系,接下來研究了MATLAB與C#數據類型轉換方法、MATLAB函數對應的.Net程序接口形式等混合編程的關鍵技術,最后通過實際項目設計了混合編程流程,編制了相關程序,驗證了MATLAB和C#混合編程的可行性。實踐表明,MATLAB和C#兩種語言的集成,能夠充分發揮各自的優勢,拓展解決問題的空間,提高系統設計和開發效率。
關鍵詞:?MATLAB; C#; .Net; 混合編程
中圖分類號: TP 393? ? ? 文獻標志碼: 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是美國MathWorks公司的科學計算軟件,以矩陣作為基本數據組織單元,集成了數據分析、無線通信、深度學習、信號處理、控制系統、金融建模和計算機視覺等眾多科學和工程領域大量優秀算法,在科學研究和工程設計等領域應用廣泛。C#是微軟公司發布的一種面向對象的、運行于.NET Framework和.NET Core之上的高級程序設計語言。C#以其較高的運行效率、強大的表示能力、優雅的語法風格、創新的語言特性和便捷的面向組件編程等特點成為.NET開發的重要編程語言。
對比這兩種編程語言,其側重的領域有所不同。C#更偏重于傳統桌面和網絡編程領域,而MATLAB更偏重于數據分析和計算領域[1-2]。為了能夠將這兩種編程語言有機融合,充分發揮各自的優勢,本文從混合編程架構、混合編程數據類型轉換、混合編程調用接口等幾個方面研究了MATLAB與C#之間混合編程的方法。
1 MATLAB與C#混合編程架構
MATLAB與C#混合編程重要概念、關鍵部分以及關鍵部分之間的聯系如圖1所示。
圖中fun1.m~fun3.m為MATLAB的M函數,僅能夠運行在MATLAB環境中,需使用MATLAB Compiler SDK中的庫編譯器(Library Comiler)將M函數轉換為.Net組件匯編[3-5],才能被C#調用。轉換過程中,可以根據業務需求和軟件設計規則將這些M函數邏輯劃分到.Net組件的不同類中。如圖1中,.Net組件名為MyComp,其下包含兩個類ClassA和ClassB,ClassA中包含fun1和fun3,ClassB包含fun2。
ClassA和ClassB中的fun1~fun3方法僅為對M函數的.Net接口,M函數的實際原代碼被加密后存儲在MyComp組件的資源區域中,名為MyComp.ctf。MyComp組件初始化時將MyComp.ctf發送至MATLAB運行時,初始化MATLAB運行環境;MyComp組件收到用戶.Net調用請求時,首先將MyComp.ctf發送至MATLAB運行時,初始化MATLAB運行環境;然后將.Net調用轉化為MATLAB調用轉發至MATLAB運行時進行實際處理;調用結束后再將返回結果轉發至用戶程序。
可見,MATLAB函數轉換后的.Net組件在實際執行過程中必須依賴MATLAB運行時。MATLAB運行時是一套獨立的共享庫,為編譯后的MATLAB程序執行提供支持。對比MATLAB,MATLAB運行時體積更小,可獨立分發和安裝,且可免費使用。
此外,在混合編程過程中,還需考慮MATLAB與C#數據類型轉換以及MATLAB函數對應的.Net接口API形式等問題,這些問題在本文后續部分詳細討論。
2 MATLAB與C#混合編程關鍵技術
2.1 MATLAB與C#數據類型轉換
MATLAB數據類型與.Net數據類型不兼容,為了使得在調用過程中能夠正確傳遞數據,MATLAB Compiler SDK提供了.Net形式的MWArray數據轉換類庫。MWArray類及其子類一方面是對MATLAB原始數據類型的封裝,另一方面其構造函數、方法、運算符重載等實現了與C#常見數據類型的轉換。因此,MWArray類庫左右銜接MATLAB與C#數據類型,實現了這兩種數據類型的轉換。
MWArray類庫層次結構,如圖2所示[6]。
其中MWArray為整個類庫的抽象基類,代表了MATLAB數據類型的抽象;MWObjectArray、MWCharArray、MWCellArray和MWStructArray為MWArray的子類,分別代表Matlab對象、字符、元胞和結構體數組;MWIndexArray為MWArray的抽象子類,代表了MATLAB可索引的數據類型的抽象;MWNumbericArray和MWLogicalArray為MWIndexArray的子類,代表Matlab的numberic和logical數組類型。
MWArray類庫可以與C#簡單變量、數組變量進行轉換。例如x、y、z分別為double變量、double[ ]一維數組和double[,]二維數組,并均已初始化數據;mwn為MWNumbericArray類型實例,則它們之間的轉換如表1所示。
表1中,可直接將double變量或double[ ]一維數組隱式轉變為MWNumbericArray類型(編號1、3),通過MWNumbericArray的構造函數可將double[,]二維數組轉換為MWNumbericArray類型(編號5);反之,MWNumbericArray類型可通過顯示類型轉換轉變為double變量(編號2),通過ToVector和ToArray方法轉變為double[ ]一維數組和double[ , ]二維數組(編號4、6)。
2.2 MATLAB函數對應.Net接口API
MATLAB中的函數在轉變為.Net組件匯編時,每個函數均會生成3種不同形式的.Net方法,分別是單輸出形式(single output)、標準形式(standard)和串接形式(feval)[7]。例如某個MATLAB函數的原型為:
funtion [Out1, ... , OutN] = foo(In1, ... , InN).
則轉變后的3種.Net方法原型為:
1) 單輸出形式(single output)
public MWArray foo(MWArray In1, ... , MWArray InN);
2) 標準形式(standard)
public MWArray[ ] foo(int numArgsOut, MWArray In1, ... , MWArray InN);
3) 串接形式(feval)
public void foo(int numArgsOut, ref MWArray[ ] ArgsOut, MWArray[ ] ArgsIn)。
這里,單輸出形式返回值為MWArray類型,適合僅有1個返回值的情況;標準形式返回值為MWArray類型的數組,適合具有多個返回值的情況,此外需通過第1個參數numArgsOut指定返回數組元素的個數;串接形式與標準形式類似,區別為不通過函數返回值而是通過按引用傳遞參數的形式從參數中返回數據。
3 MATLAB與C#混合編程應用
3.1 應用案例
在筆者實際項目中,需定時通過安裝在水底管道表面的監控傳感器采集管道中的聲波信號,計算聲波的功率譜密度,進而通過功率譜密度分析判斷管道是否有裂紋及其破損程度。設計方案使用C#程序連接監控傳感器獲取原始聲波信號,而后將聲波信號傳遞至自行編寫的MATLAB函數,函數內部使用MATLAB的頻譜分析函數計算聲波信號的功率譜密度。此過程中涉及MATLAB與C#的混合編程。
3.2 混合編程流程及實現
核心算法的混合編程流程主要分為以下4個步驟:
1) 在MATLAB中編寫計算功率譜密度的函數ComputeFFT,參數data為按時間采集的信號向量,interval為采集時間間隔,返回頻率freq和功率譜密度powerSpect兩個向量。
function [freq, powerSpect] = ComputeFFT(data, interval)
fftData = fft(data);
N = length(fftData)
freq = (0:N-1)/(N*interval);
powerSpect = abs(fftData)/(sqrt(N));
2) 通過MATLAB Compiler SDK將MATLAB函數ComputeFFT轉變為.Net組件,組件名和命名空間為SpectraComp,類名為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#程序中引用基礎組件MWArray.dll和上述步驟生成的組件SpectraComp.dll,并啟用相關命名空間:
using MathWorks.MATLAB.NET.Arrays;
using SpectraComp;
4) 在C#中調用SpectraComp組件的ComputeFFT方法計算功率譜密度。這里采用標準API形式,第1個參數為返回值個數,第2、3參數為聲波信號及采樣時間間隔,按照MWArray類型轉換規則,后兩個參數會被自動轉變為MWArray類型。返回值argsOut為MWArray[]數組,包含2個元素,argsOut[0]表示頻率向量,argsOut[1]表示功率譜向量,最后使用MWArray的ToVector方法將上述兩個向量轉變為C#一維數組
const int N = 1024; #每次采集數據個數為1024
const interval = 0.001; #數據點間隔為0.001秒
#數組data用于存儲聲波信號
double[ ] data = new data[N];
……
#計算功率譜密度
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);
……
某次采集的時域聲波信號和對應計算的功率譜密度,繪制圖形如圖3所示。
4 總結
MATLAB作為重要的數值計算軟件,包含大量優秀算法庫,廣泛應用于科學研究和工程設計等領域。MATLAB Compiler SDK作為MATLAB組件,能夠將MATLAB函數庫轉變為.Net組件匯編庫,簡化了MATLAB程序與C#程序之間的混合編程方案。本文研究了MATLAB與C#混合編程的宏觀架構以及關鍵技術,設計了混合編程流程,編制了相關程序。實踐表明,MATLAB和C#兩種語言的集成,能夠充分發揮各自的優勢,拓展解決問題的空間,提高系統設計和開發效率。
參考文獻
[1]
王文斌,剡昌鋒,劉朝陽,等.MATLAB繪圖窗嵌入.NET項目混合編程[J].計算機工程與設計,2015,36(12):3413-3417.
[2] 鄭建波,于生寶,蘇發,等.C#與Matlab混合編程的CSAMT靜態校正軟件設計[J].實驗室研究與探索,2016,35(7):113-116.
[3] 陳柳松,楊利,張宇,等.基于.NET程序集的C#與Matlab混合編程技術及應用[J].控制與信息技術,2018(2):44-46.
[4] 劉亞,王靜,田新誠.基于C#和Matlab混合編程的軸承故障診斷系統[J].計算機應用,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)