通过QT实现进程间的通信
2019-09-07王惠军
王惠军
(山西大众电子信息产业集团有限公司,山西 太原 030024)
0 引言
Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。QT支持Windows、Unix、Android、iOS等多种操作系统,具有优良的跨平台特性。Qt具有良好封装机制,使得Qt的模块化程度非常高,可重用性较好,各个元件之间的协同工作变得十分简单。QT还包含丰富的API,包括多达250个以上的C++类,还提供基于模板的Date/Time、Serialization、File、Collections、I/O device、Directory management类。基于以上Qt的众多优点,使用QT开发程序会更加的方便、高效、简单。下边就介绍如何在Windows操作系统下,通过QT实现进程间的通信。
1 环境的搭建
首先介绍QT的开发和运行环境。操作系统选择Win7 64位,QT版本为5.0.2,C编译器版本:VS2010,调试工具为Windbg,设置好的系统环境变量包含C:QtQt5.0.2·.0.2msvc2010_openglin、C:WindowsSystem32、C:Program Files (x86)Microsoft Visual Studio 10.0VCin、C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDE。
2 设计思路
基于QT开发程序,可通过消息队列、信号、共享内存、套接字等方法实现进程间的数据通信。本文主要介绍如何通过套接字和共享内存相结合的方法实现进程间的通信。
设计思路如图1所示。建立两个应用程序,在程序中分别开辟相同的共享内存,建立套接字,共享内存用来保存数据,套接字用来发送和接收数据已更改的消息。在第一个程序中输入数据,数据变化后,修改共享内存中内容,同时向第二个程序发送数据已更改的消息,第二个程序收到数据已更改的消息后,在共享内存中读取最新的数据,并显示在界面上。
图1 设计思路
3 实现
3.1 T1的实现方法
首先介绍第一个程序(T1)的实现方法。
1) 在QT Creator中新建Qt Gui应用程序,在名称编辑框中输入T1,其它默认。
2) 添加输入界面。在界面中添加“LineEdit”控件,添加槽textEditChange(),用来接收输入变化的消息。
3) 修改头文件。添加的内容见表1。
表1 头文件mainwindow.h
第1行和第2行分别包含了头文件“QSharedMemory”、“QtNetwork/QUdpSocket”,其中加载QSharedMemory表示可调用共享内存的函数,加载QtNetwork/QUdpSocket表示可调用套接字的函数。
第5行到第7行定义了与共享内存有关的变量和函数。
第8行到10行定义了与套接字有关的变量和函数。
第12行定义了槽,用来接收数据变化的消息。
4) 修改CPP文件。在mainwindow.cpp中,需要对CreateShareMem函数、initSocket函数、TextEditChanged函数进行修改。
修改结果见表2。
第1行为共享内存指针分配了地址;第2行设置了共享内存的关键字;第3行将共享内存与本程序解绑,保证其它进程也可访问该共享内存;第4行设置共享内存的大小。
第5行用来创建套接字,给套接字指针分配地址;第6行用来绑定IP地址和端口号,绑定的IP地址是本机地址,端口号是7755。
第7行和第8行用来判断共享内存指针是否与本进程绑定;第9行将共享内存的数据锁定;第10行得到共享内存的大小;第11行得到界面中输入的数据;第12行得到界面输入数据的长度;第13行将共享内存的大小与数据长度进行比较,保证写到共享内存中的数据不会溢出;第14行将界面中的数据复制到共享内存中;第15行将共享内存的数据解锁,保证其它进程可以读取共享内存中的数据;第16行调用发送套接字消息的函数,将数据已更改的消息发送到第二个程序。
表2 修改结果
经过以上过程,第一个程序就完成了,接下来介绍第二个程序(T2)的实现方法。
3.2 T2的实现方法
T2项目的创建方法与T1项目的创建类似,在名称编辑框中输入T2,其它设置与T1项目一致。
1) 添加输入界面。在界面中添加“LineEdit”控件,添加信号signal_TextChanged(QString)。在信号和槽编辑器中添加连接,发送者是MainWindow,信号是signal_TextChanged(QString),接收者是LineEdit,槽是SetText(QString)。
2) 修改头文件。T2项目的头文件与表1的内容类似。
3) 修改CPP文件。在mainwindow.cpp中,需要对CreateShareMem函数、initSocket函数、readPendingDatagrams函数进行修改,其中CreateShareMem函数与T1项目的内容完全一致,initSocket函数中,绑定的端口号为7756,同时添加信号连接,用来响应套接字收到数据的消息。
修改结果见表3。
表3 readPendingDatagrams函数修改结果
第1行到第5行定义了函数中需要用到的变量,包括套接字的数据、地址、端口号,共享内存的数据;第6行判断套接字是否收到数据;第7行通过套接字指针读取收到的消息,同时返回消息的内容、长度、IP地址和端口号;第8行到第13行表示从共享内存中读取数据,与表7中第1行到第9行的含义一致;第14行将最新的数据通过信号发送给LineEdit控件。
经过以上过程,第二个程序就完成了。
3.3 结果显示
分别对两个程序进行编译,编译成功后运行T1.exe和T2.exe,在T1中输入信息后,T2会同步进行显示,如图2所示。
图2 运行结果
4 结束语
本文通过一个简单的例子实现了进程间数据的通信,通过套接字与共享内存结合的方式,可实现不同进程间数据的实时同步,通过改变套接字的消息类型,可实现不同种类数据的同步,在工程应用中有重要的意义。