C#与Matlab集成编写Windows GUI耗时程序
C#与Matlab集成编写Windows GUI耗时程序
Astrophel最近在编写一个简单的遥感影像处理程序,技术路线是使用Matlab实现一个较为耗时和复杂的数据处理后端,使用VS C#(.NET Framework)实现一个简单的前端GUI界面。
由于这方面网上的资料比较多,本来没打算写(水)一篇博客的,但是实现过程中遇到了不少坑和疑问,所以还是统一记录一下。
Matlab后端运算打包dll
由于遥感影像处理多涉及矩阵运算,因此使用Matlab进行编程。将所有代码写成函数后,在“附加资源管理器”中下载并安装MATLAB Compiler和MATLAB Compiler SDK两个附加包。
在App选项卡打开Library Compiler功能,在TYPE栏选择.NET Asswmbly,在EXPORTED FUNCTIONS栏添加自己想要编译的函数。如果想要打包结果不包含Matlab运行时(MCR)以节省空间,则在PACKAGING OPTIONS中选择第一个选项,在未安装Matlab本体的计算机上运行时,选择该选项需要用户手动下载并安装免费的MCR或购买Matlab本体;否则,选择第二个选项,打包包含MCR的完整包,会占据较大空间。另外,如果被打包的函数使用了其他函数,该工具会自动一并打包,不需要额外添加。
以本程序changeDetection
为例:打包完成后,打开包体位置,找到“for_redistribution_files_only”文件夹,复制changeDetectionNative.dll
到VS的项目目录中。
(至于changeDetection.dll
文件,官方给出的解释为)
1 | -changeDetection.dll-contains the generated component using MWArray API.-changeDetectionNative.dll-contains the generated component using native API. |
然后,前往 .\matlab\toolbox\dotnetbuilder\bin\win64\v4.0
路径,复制MWArray.dll
到VS项目目录。至此,在Matlab中的工作已经结束。
Visual Studio中创建GUI
在建立好的Windows窗体应用程序中绘制UI界面并添加上文中两个dll文件的引用。使用时,需在对应代码文件前添加using MathWorks.MATLAB.NET.Arrays;
和using changeDetectionNative;
以实现调用。
调用的Matlab函数返回值为一个object
类,如果有多个返回值,将在该类中以数组形式储存。函数的传入参数前需添加一个整数,用以代表返回值的个数。具体示例如下:
1 | ChangeDetection CD = new ChangeDetection(); |
如果时计算耗时较短的Matlab程序,至此即完成了前后端的集成。
耗时程序的处理
对于耗时程序,在后端运算时,前端的GUI窗体会发生假死的状态,表现为UI无法更新,无法拖动,无法操作。显然,这样不符合一般用户的直觉。而遥感影像处理的Matlab后端程序基本上都需要消耗较长的时间,因此了解C#中耗时程序的处理是有必要的。
出现该状况的原因在于,后端的计算过程占用了UI更新的主线程,导致程序无法处理相关操作。解决方法也很简单,使用异步操作使程序以多线程的形式运行即可。
在C#中,使用await运算符(异步等待任务完成)创建多线程很容易,首先在执行按钮的函数中添加修饰词async,即private **async** void button1_Click(object sender, EventArgs e)
,然后将前文的代码改为:
1 | ChangeDetection CD = new ChangeDetection(); |
这样,在程序运行时,UI界面就可以正常更新和操作了。
至此,Matlab集成C#的遥感影像处理程序的技术框架大致构建完成,只需要继续添加需要的功能即可。