亓雪冬 李霞
摘 要: 研究了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)