目录
1.MF文件路径
2.服务必须要接口类
3.插件名命名要求
4.生命周期问题
5.一个接口对多个实现注意
6.中文输出注意
7.同一插件安装注意
8.添加元数据
9.关于升级插件时遇到的问题
10.不同插件定义资源文件注意路径问题
11.安装插件
12.插件依赖
1.MF文件路径
在编写插件添加资源文件的过程中,MF文件的路径前缀必须和MF文件中的Plugin-SymbolicName必须相同,而且也需要和生成的dll名字一致,在qtcreator中也就是TARGET,如下图:
在vs2019中设置目标文件名为MF的路径前缀,如下图:
我遇到的大部分插件加载不起来(安装失败)的原因就是插件找不到.MF文件,所以出现问题的时候就要去仔细检查下几个地方的名称是否一致。
2.服务必须要接口类
刚开始我有个想法,为什么必须要有接口,感觉多此一举,需要的功能在实现类就能完全体现了。可不可以只有实现类+激活类,如下工程:
结果是不行的,原理还不知道,反正使用这个dll就会报错:
总结上面:
①、如果一个类不继承一个接口类,那么这个类是不能使用registerService注册到ctk框架的,如果强行注册,在安装和启动此插件的时候就会报错;
②、但是完全可以使用一个没有继承接口类的类,如何使用呢?首先定义类的功能函数,如定时向ctk发送事务,然后通过在Activator的start开启这个类的定时器,这样虽然能够正常使用,但是却无法通过ctk获取到这个插件,毕竟它不是服务【无法注册成服务】,它的作用在Activator的start里就已经用掉了。
③、如果实在不想写接口类,可以继承ctk提供的ctkEventHandler类,这个类主要用于提供插件间通信【event方式】,然后把其他函数定义成当前类自己的函数就行了。
3.插件名命名要求
生成的插件名不要有下划线,因为CTK会默认将插件名中的下划线替换成点号,最后后就导致找不到插件。
4.生命周期问题
如果想把ctk初始化、插件安装启动、获取等操作封装成一个类,那么要注意:需要把ctk相关的变量定义成类属性,不能是局部变量,否则会出现各种问题如获取不了服务、服务引用为空等。
ctkPluginFrameworkFactory frameworkFactory;
ctkPluginContext* context = nullptr;
5.一个接口对多个实现注意
在使用1个接口多个插件的时候,虽然是多个插件,也会有多个激活类【从原理上来讲1个激活类就行了,但是在start里注册两次】,其中的IID只能有一个,
如果有两个会出现报错:
应该是从Qt插件基础上来说,一个dll只能有一个IID
6.中文输出注意
使用CTK的时候,尽量不要使用中文【qDebug】,不然可能会打印乱码;有时候加中文可能都直接编译不过。
7.同一插件安装注意
经过实测:同一路径的插件是可以多次安装、启动,并且不会报错,并且它们的id是一致的【相当于如果安装已经安装了某路径的插件,会直接返回】;但是将这个插件放在不同路径是会安装失败的。
注意,这里的同一插件是指插件名称,而不是MF里的name
8.添加元数据
可直接在MF文件里添加自己特有的元数据,如:
9.关于升级插件时遇到的问题
即使是被停止、卸载的插件,还是被框架占用,无法对其删除,可以复制;
某个插件刚开始安装的时候是V1.0,卸载之后第二次安装的时候是V2.0,此时插件提供的接口都更新成功,但是通过读取MF文件的headers还是V1.0的信息;
同一路径的某插件,安装多次,虽然不会报错,但是除了第一次,后面全部都直接返回,不会对框架产生任何变化,把第一次安装成为有效安装。【如安装A-安装A-安装A,只有第一次安装才是有效的,后面没有任何作用】;
同一插件【接口名称相同,实现可以不同,版本也可以不同】放在不同路径,如果都安装了,那么调用的接口是最后那次”有效”’安装的插件的。【如安装A-安装B,那么最后调用的B;安装A-安装B-安装A,最后调用的是B,因为最后一次安装A是无效安装】;
如果生成了a.dll插件,我们手动把命名改成了a.1.0.0.dll,此时是无法安装成功的;
10.不同插件定义资源文件注意路径问题
不同插件定义资源文件时,如果不同资源文件路径相同,那么插件在使用资源文件时,只会访问到一个。
如A、B插件都定义了qrc:\xxx\yyy.img,两个插件内部使用这个图片时,显示的是同一个图片;包括qml也是一样的。
可能这也是ctk插件发布时需要前缀不一样的原因
11.安装插件
使用pluginContext->installPlugin(QUrl::fromLocalFile(pluginPath))
方法安装插件,其中pluginPath是插件文件的本地路径。安装成功后,将返回一个表示已安装插件的对象。如果安装过程中发生错误(如插件文件不存在、格式错误等),将抛出异常,需要进行异常处理。
12.插件依赖
确保插件所需的所有依赖项都已正确配置。如果插件依赖于其他库或插件,这些依赖项必须在插件加载之前被正确加载和初始化。