新闻中心

EEPW首页 > 测试测量 > 设计应用 > 基于Qt与MATLAB的混合编程技术

基于Qt与MATLAB的混合编程技术

作者:周珊珊 朱桐 胡杨时间:2016-09-28来源:电子产品世界收藏
编者按:在Qt雷达仿真系统中,数据处理及图形显示尤为重要。本文为此提出了一种Qt与MATLAB混合编程的方法。通过VC++和MATLAB混合编程技术,将MATLAB函数封装成动态链接库,Qt调用这个动态链接库实现图形处理功能,从而改善Qt界面中雷达信号仿真问题。

摘要:在雷达仿真系统中,数据处理及图形显示尤为重要。本文为此提出了一种的方法。通过VC++和技术,将函数封装成调用这个实现图形处理功能,从而改善Qt界面中雷达信号仿真问题。

本文引用地址:http://www.eepw.com.cn/article/201609/310493.htm

引言

  Qt是一个跨平台的C++图形用户界面应用程序开发框架。它包括跨平台类库、集成开发工具和跨平台IDE[1]。由于强大的跨平台特性,使用Qt只需一次性开发应用程序,无须重新编写源代码,便可跨桌面和嵌入式操作系统运行。在图形处理方面,Qt提供了用于2D绘图的QPainter绘图类和第三方绘图库Qwt,可以绘制简单的图形,但其过程复杂、设置繁琐,且操作过程不易实现。

  MATLAB作为一种高性能的数值计算和可视化软件,它集数值分析、矩阵运算、信号处理和图形显示于一体, 构成了一个方便、界面友好的用户环境。相比Qt而言,MATLAB有非常强大的图形化显示矩阵和数组的能力,用MATLAB生成的图形可轻松实现添加文字说明、标注坐标轴、曲线注释等多种功能,而这些若由Qt来实现则较为复杂。针对Qt的绘图缺点,提出了Qt与MATLAB技术,主要包括两种方法:Qt调用MATLAB的引擎和Qt调用MATLAB生成的。Qt调用MATLAB引擎加入大量MATLAB库,功能十分强大,但其编程量巨大,运行效率较低,不利于开发使用。而使用MATLAB生成的动态链接库使程序可以脱离MATLAB环境独立运行,节省程序所占用的内存资源,提高了程序的执行效率。当然,由于MATLAB7.0前后不同版本编译器的不同特点,混合编程方法也会有所不同。下面本文将详细介绍如何将MATLAB函数转换为Qt可用的DLL的方法,并应用到Qt雷达仿真系统工程中。

1 Qt图像显示窗口

1.1 显示窗口

  Qt可以使系统获得高效的工作性能,是因为它拥有一个重要机制——信号和槽机制[2]。信号和槽用于两个对象之间的通信,信号和槽机制是Qt的核心特征,也是Qt不同于其他开发框架最突出的特征。QWidget类是所有用户界面对象的基类,是Qt中建立用户界面的主要元素。在雷达仿真系统中,将图形显示模块作为一个封装的窗口组件嵌入到系统中,窗口组件主要以窗口部件QWidget为基类,嵌入MATLAB的Figure窗口[3],使用信号和槽等实现数据处理和图形绘制。

1.2 绘图需求

  随着雷达技术的不断发展,雷达系统的复杂度与日俱增,雷达系统的设计越来越多地借助仿真来提高工作效率。一套完整的Qt雷达仿真系统必不可少的就是图形显示,用于直观地观测雷达各个模块的波形及运动轨迹。Qt提供了2D绘图系统[2],可以使用API在屏幕和绘图设备上进行绘制,主要基于QPainter、QPaintDevice和QPaintEngine这3个类,其中QPainter用来执行绘图操作,QPaintDevice提供绘图设备,QPaintEngine提供了一些接口。同时,Qt的第三方绘图库QWT可生成各种统计图,它的目标是以基于2D方式的窗体部件来显示数据。然而这两种绘图方法的编程过程比较复杂,尤其在处理大量数据和三维图形显示时更是难以实现。MATLAB有强大的图形化显示矩阵和数组的能力,同时也能给图形增加注释并且打印这些图形。它既包括一些方便地产生二维、三维技术专业图形的高级绘图函数,也包括一些可以使用户灵活控制图形特点的低级绘图命令。另外,用户还可以利用MATLAB的句柄图形技术创建图形用户界面[4]。这种语言可移植性好、可拓展性极强,所以采用Qt与MATLAB混合编程的方法,才能实现强大的图形处理功能。图1为雷达目标检测仿真结果图。

2 Qt调用动态链接库

2.1 Qt调用动态链接库流程

  Qt调用动态链接库主要有两种选择方案,一种是利用VC++调用MATLAB生成的独立可执行的C++函数文件创建集成的绘图动态链接库,Qt窗口组件来调用它;另一种是Qt直接调用MATLAB生成的独立可执行的C++函数文件创建集成的绘图动态链接库,然后Qt窗口组件使用这个动态链接库文件。由于VC++与MATLAB混合编程技术相对比较成熟,并得到广泛应用,所以我们选用第一种方案。图2展示了在Qt中调用动态链接库的步骤。

2.2 VC++动态链接库嵌入到Qt中

  Qt窗口组件调用VC++动态链接库,实现绘图和图形显示功能,在工程目录中添加上述dllMATLAB.h、dllMATLAB.dll和dllMATLAB.lib文件。在工程的管理文件.pro中加载需要连接的动态链接库,添加代码“LIBS+= -L ./ -ldllMATLAB”。在头文件中添加动态链接库提供的头文件的“dllMATLAB.h”。这样我们就可以调用MATLAB函数库中的绘图相关函数,对数据进行图形处理了。

  但是调用显示的Figure窗口却是单独显示的,与Qt中窗口组件不一致,为使界面风格统一,用户界面美观,我们需要将MATLAB的Figure窗口嵌入到Qt窗口组件中。这种方法的基本思路是去除MATLAB 的Figure窗口的标题栏及边框,然后把它移动到Qt窗口组件中,同时设定Qt窗口组件为父窗口。具体由以下代码实现。获取MATLAB 的Figure窗口句柄:

  HWND hfigure =FindWindow(NULL,str.toStdWString().c_str());

  获得Qt窗口组件的句柄:

  HWND centralWidget = (HWND)(this->winId());

  设定Qt窗口组件为Figure窗体的父窗体:

  if(NULL==::SetParent(hfigure, centralWidget))

2.3 创建VC++动态链接库

  要想在Qt中调用MATLAB的各种绘图函数,满足工程需要,使用动态链接库无疑是最好的选择。

  动态链接库[6]是Windows操作系统中实现共享函数库概念的一种方式,使进程可以调用不属于其可执行代码的函数。DLL可以采用多种编程语言来编写。例如,可以利用Qt来编写程序界面,然后调用VC++编写的完成绘图功能的DLL。动态链接库有助于共享数据和资源,简化项目管理,节省磁盘空间和内存,更易于升级。

2.4 MATLAB数据类型与VC++数据类型相互转化

  我们知道在MATLAB当中运算都是基于矩阵的,因此,在VC++中调用MATLAB函数时,无论函数的返回值、参数必须是矩阵类型(mwArray)[7],而在C++当中的二维数组可以看成一个矩阵,在VC++当中可以用下面的函数将数组转化成MATLAB中的矩阵类型。例如data= new double[m*n],可以用mwArray mwdata(m,n,data);这样就可以将二维数组变量转化成mwArray 类型,进而可以作为MATLAB函数的参数。反之,把mwArray 类型的变量转化成C++中的二维数组:例如存在mwArray 变量mwdata,用函数size获得矩阵的大小,row=size(&col,mwdata),其中row,col是函数的返回值,data=new double[row*col];data.ExtractData(mwdata); 这样就可以把mwArray类型转化成数组类型。另外,用GetData()和mxGetPr、mxGetPi组合可以得到指向mwArray对象的指针。

3 VC++和MATLAB混合编程

3.1 VC++与MATLAB混合编程步骤

  在工程实践中,VC++调用MATLAB 的方法主要有两种:调用MATLAB计算引擎和调用MATLAB生成独立可执行的C++函数文件。为满足工程需要,选择第二种方法。

3.1.1 在MATLAB中进行编译器设置

  MATALB编译器是一个运行于MATLAB环境的独立工具。其主要功能是把M程序转换成C/C++代码,然后再调用外部C/C++编译器,把产生的源代码编译、链接成用户指定的格式[4]

  需要在MATLAB环境中配置外部C/C++编译器,在MATLAB命令环境行输入mbuid-setup设置要用到的C/C++编译器。输入mex-setup对MEX文件进行配置编译。

3.1.2 新建M文件并编译

  (1)建立M文件,将工程中需要用到的数学函数库和图形库中的常见函数plot、mesh、hist、image、figure、fft、contour、set、get等函数编写成M函数。功能相同的函数,参数个数不同时要视为两个不同函数。

  (2)利用mcc命令编译M文件,在MATLAB环境中使用mcc命令将M文件编译成可独立执行的C++函数文件。

3.1.3 在VC++中进行编译环境设置

  首先设置系统变量,在系统环境的用户变量添加MATLAB及VC++软件的安装目录。然后在VC++设置编译环境:

  (1)添加MATLAB库的头文件和库函数的路径;

  (2)设置运行时动态链接库;

  (3) 导入静态链接库文件。

3.1.4 创建动态链接库

  动态链接库是将功能封装在一起的模块,因此,与代码直接写入调用模块中相比,它不仅可以提高程序的复用,减少代码开发工作量,同时也可以节省内存,提高代码利用率。

  VC++调用MATLAB混合编程生成可以独立运行的C++代码,创建动态链接库,通过静态加载或动态加载的方式来使用DLL。新建一个空的动态链接库工程,添加一个头文件dllMATLAB.h和源文件dllMATLAB.cpp。将mcc编译后生成的C++文件添加到项目中,对MATLAB中M文件中的函数重新定义,满足MATLAB数据类型与VC++数组类型相互转化。编译生成dllMATLAB.dll和dllMATLAB.lib文件。这样其他应用程序只需将dllMATLAB.h、dllMATLAB.dll、dllMATLAB.lib添加到工程目录中就可以使用这个动态链接库,实现调用MATLAB的绘图功能了。

3.2 MATLAB不同版本的区别

  值得注意的是,不同MATLAB软件版本导致混合编程的方法不同。与之前版本相比,MATLAB7.0之后的版本的编译器发生了较大变化。其主要新特点及变化包括以下两个方面:一、不再提供C++数字库和图形库;二、不再编译所有的M函数,只是产生必要的C/C++接口函数。

  所以VC++调用不同版本的MATLAB的动态链接库的过程也有很大差别,具体表现在三个方面。

3.2.1 mcc命令及编译产生C++文件不同

  MATLAB7.0之前的版本编译命令为:mcc - B sglcpp (文件名),参数“ - B sglcpp ”含义是将. m文件编译成为C++代码,生成.cpp和.hpp文件,提供图形库支持, 并编译为独立运行的exe程序。

  MATLAB7.0之后版本使用mcc命令。假设要把M文件编译成C语言动态链接库文件“mcc -W lib:(对应链接库名称) -T link:lib (文件名M)”。假设要把M文件编译成C++语言动态链接库文件:“mcc -W cpplib:(对应链接库名称) -T link:lib (文件名M)”。这里我们采用第二种方法编译运行之后,在目录下面将会出现以下以.lib、.dll、.exports、.exp、.h和.cpp为后缀的6个文件。

3.2.2 在VC++工程中头文件及初始化设置等不同

  在MATLAB7.0以前,在VC++程序中使用MATLAB编译器产生代码时,必须在VC++源程序中分别包含MATLAB.hpp。从MATALB7.0起,MATLAB的编译器不再提供MATLAB.hpp,代之以mclmcr.h。

  另外,在调用MATLAB初始化设置时,MATLAB7.0以前采用以下代码:

  void initialMATLAB() //初始化设置

  { libmmfileInitialize();//初始化MATLAB数学库

  libmwsglmInitialize();//初始化MATLAB图形库

  mlfHGInitialize(NULL,NULL);}

  MATLAB7.0之后版本编译产生的动态链接库,对每个M文件都有初始化及释放设置,也就是说不需要整体的初始化及释放设置,只需对使用的函数进行初始化,具体参考MATLAB帮助。

3.2.3 程序发布方法有所不同

  由于程序中调用了MATLAB 数学函数库或图形库中的函数,MATLAB7.0之前版本需要附带MATLAB的这些函数库才能在没有安装MATLAB 的机器上运行。以MTALAB6.5为例,我们需要收集libmmfile.dll、libmwservices.dll、libut.dll等函数库,并将这些文件添加到应用程序Debug目录或者Release目录下,这样程序就可以未装MATLAB软件的机器上运行,简化了MATLAB与C/C++的混合编程,可移植性强。

  MATLAB7.0之后版本的编译器不再提供C++数字库和图形库,而是使用MATLAB组件运行环境MCR(一组标准的动态链接库),它提供了运行编译后的程序所需的基本环境[4]。所以要想程序发布到别的没有安装MATLAB的计算机上使用,必须在目标计算机上安装MCR,其文件位于MATLAB 安装目录的externlibwin32子目录MCRInstaller.exe,运行MCRInstaller.exe程序即可自动把需要的库函数解压到当前目录中,这样程序就可以脱离MATLAB运行。

  通过对比发现,不同版本各有优势,在我们的工程项目中选用了MATLAB6.5,这样要想发布VC++创建的动态链接库只需收集库文件,虽然收集过程复杂,但是可移植性强,灵活性高,用户操作简单。

4 总结

  本文采用Qt与MATLAB混合编程的方法满足了Qt工程中对数据处理和图形显示的要求,增强了Qt的绘图功能。经过项目的实践,调用MATLAB生成的可独立执行的动态链接库在项目中得到了较好的应用。当然,集成的动态链接库还需要进一步地完善来满足不同的项目对绘图及复杂数值运算的要求,为用户提供功能强大的开发平台。由于Qt优良的跨平台特性和MATLAB的图形处理功能,相信未来Qt与MATLAB的混合编程在嵌入式系统的应用前景会更加广阔。

参考文献:

  [1]霍亚飞.Qt Creator快速入门(第2版)[M].北京:北京航空航天大学出版社,2014.

  [2]丁林松,黄丽琴.Qt4图形设计与嵌入式开发[M].北京:人民邮电出版社,2009.

  [3]张亮,王继阳等.MATLAB与C/C++混合编程[M].北京:人民邮电出版社,2008.

  [4]董维国.深入浅出MATLAB7.x混合编程[M].北京:机械工业出版社,2005.

  [5]魏鑫,陈辉强,高飞.Qt与MATLAB的混合编程究与实现[J].计算机与现代化,2010,9(1):168-170.

  [6]孙鑫,余安萍.VC++深入详解[M].北京:电子工业出版社,2006.

  [7]刘维.精通MATLAB与C/C++混合程序设计(第2版)[M].北京:北京航空航天大学出版社,2008.

  [8]马兴义.MATLAB6应用开发指南[M].北京:机械工业出版社, 2002.

  [9]张明友,汪学刚.雷达系统(第2版)[M].北京:电子工业出版社,2006.

本文来源于中国科技期刊《电子产品世界》2016年第9期第57页,欢迎您写论文时引用,并注明出处。



评论


相关推荐

技术专区

关闭