赞
踩
自Qt 5.9之后,Qt推出了一个框架库,Qt称作Qt Remote Objects(QtRO),我自己翻译为远端可调用对象哈哈,不像其他的Qt功能库,这个是没有示例工程的,只有一个在帮助手册overview里面的三个例子,那么先说明Qt的RO是什么
首先,进程通信一般分为 消息队列,共享内存,管道(有名和无名),TCP/UDP等,也就是IPC的绝大多数机制,当然TCP和UDP可以具有RPC的机制,如果你要写的话;
传统的进程通信已经无法满足分布式等跨越机器网络的函数调用、耦合度降低、可扩展等情况,那么就需要一些可以复用的框架扩展,于是出现了COM通信调用,ICE框架等,但是使用这些框架有问题在于平台的兼容问题;那么问题来了,如果自己拿Qt的原有框架写要怎么写一个呢,我想大家无非就是想QT现在做的一样,自己搞一个映射吧
那么可以猜测我们要这样子写
1、建立通信 :TCP或者管道,建立客户端和服务
2、定义模板,需要公布对外的函数,对象,使用字符串发布到服务,或者协议内
3、建立自身的函数接口映射,当服务器发送消息的时候调用对应的函数和参数
4、管理自身的连接
以上几部只是大概的按照工作经验猜测Qt的RO逻辑,实际上也差不多,那么可想而知,Qt的qml通信,QT和web的包裹通信也是应该是使用这个机制,研究这个机制,也就很容易了解了其他几个的机制,在编写代码的时候,也会很清楚写的意义,好了,下面我们开始学习QT的示例代码
例子1 单机静态编码直连
帮助手册翻译
1.第一步,创建一个Rep文件(但是我个人觉的还是先创建一个控制台工程,再添加该文件)
QT示例代码如上
该文件作用是一个模版,用于后面由Qt目录下面的repc编译生成对应的一些代码,有点像信号与槽,之后生moc文件或者ui生成xxx_ui.h文件
PROP是在手册里面有说明,表示是一个属性,QT元对象系统里面对应会生成QProperty声明,qml也是类似,声明作用在于会生成对应的读写、信号等函数操作,而且都可以对外调用
类似的宏可以看Qt手册里面的解释
SLOT就不用说了,是声明一个槽函数
2.添加到工程中(这个也就是为什么我说最好先创建工程的原因)
在工程文件目录下添加该文件,并且把该文件声明到.pro文件中
我的文件名称自己改了
REPC_SOURCE的作用在于,告知qmake,这个是一个rep的资源文件,后面需要调用repc去编译生成一个头文件
需要注意的是 QT += remoteobjects需要先添加,否则没办法识别出来
添加完成之后可以试着编译一下,正常情况下会在生成目录下生成一个头文件,该头文件
该头文件大致是这样子,个人称作为模版源文件
该文件用来干什么呢,其实就是之前说的,里面有三个类
一个实现了函数的映射,一堆的映射,正常人都可以完成,所以Qt帮我们完成了
一个是接口类,后面用于实现继承,当然QT已经帮我们实例化继承了,这个纯虚类,主要是对外的接口解耦使用
一个是实例化上面接口的类,他实现了之前定义了模板的函数和属性,我们要使用的就是这个类型,好像会自动添加一个simple字符
3. 实现模板编译出来的类型(注意需要qmake编译一下)
在生成了xxx_source.h文件之后,编写一个新的类型
继承类型如上,来自repc编译生成的头文件中的类
需要说明的是,之前模板中的server_slot函数默认是没有做事情的,所以需要重写,然后才能使用,记得使用virtual,否侧调用会不正常,这个是虚函数的知识,具体可以自行搜索
其他的都是一堆测试的函数,里面搞了一个计时器,在自己初始化的时候开始修改自己的状态,也就是模版里面定义,在repc编译后生成属性和对应的函数 current
红色的函数就是由于repc编译生成的函数,继承后继续使用
至此,我们的工作完成了一大半,该调用测试一下
代码还是来自Qt的示例,修改了一点点
说明:创建了client之后其实就开始调用状态修改了,后面的代码对于单程序测试没有用,但是要在这里说明,因为下面两个程序一起执行的时候这个意义就有了
首先创建了一个host,看这个是一个字符串,表示本地连接,关键词test,这个猜测QT内部可能使用了下面这个qt的类
该类型是一个本地程序通信的类,需要一个关键词识别连接
编译执行程序效果如下:
这个程序很简单,就算写一个简单的类也可以,但是这个用于后面
4.新建客户端工程
把上一个工程里面的那个模板rep文件复制或者引用添加到当前工程,然后在工程中添加
完成之后应该是上面的样子,编译测试一下,会在工程的生成目录下生成一个xxx_replic.h文件,称作可调用对象,也就是客户代理对象
该对象都已经按照模板实现了所有的函数
5.编写调用该代理类型
按照示例代码,重点是初始化里面,和代理对象进行了连接
完成了上述代码,之后就是使用该类
在main中实现使用该对象,其中第一步是创建客户端,连接,关键词和之前创建的程序必须相同
第二步是创建代理对象,也就是该对象会和最先创造的程序连接
之后创建客户端类,主要工程就是信号槽连接,在发生变化的时候打印出来而已
至此,一个本地的RO就连接好了,运行两个程序
效果如上,也就是说,第一个程序建立了服务,把代理对象注册到网络,允许其他人知道他的存在和调用
第二个程序连接服务,被告知,你可以使用的程序如上,之后他的状态变化了也就被第二个程序知道了,那么这个学习也算是告一段落,如果需要跨越pc,其实是类似的
Qt给的第二个例子,使用的动态调用,方法很像qml动态注册之后动态写入属性的办法,动态调用的意义在于不需要repc编译客户端rep文件,而是直接写代码调用即可
步骤如下:
1.之前例子中的服务端的代码不变,编译就好
2.修改上述例子中的代码
针对代理类client修改为Qt的默认类型,这个类型也是repc编译生成的类型使用的基类
在main中修改调用方法,动态的获取,按照之前服务端rep的名称获取
名称可以参考服务端自动生成的文件上面标注地方
编译两个程序执行
生成结果一样,除了警告
如果需要使用网络,则只需要修改地址即可:
1.修改main代码
左侧为客户端代码,右侧为服务端代码
按照QT例子需要注册,但是实际上好像去掉也可以连接
运行程序,虚拟机里面IP是192.168.104 建立服务端
物理机ip是103
运行结果
看来Qt有些东西也是理解不清楚,感觉注册不需要
经过多种测试,应该是这样子使用注册地址
也就是说,只有两边都使用注册的时候,连接会自动连接上
另外,关于Qt的网络连接的使用,QT还提供了额外的玩法
就像帮助手册里面的一样,可以提供对TCP的控制,那么也就是可以使用多线程操作我们需要的tcp,如果有必要的话
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。