CTK插件框架学习4-创建跨平台插件工程「建议收藏」
发布时间 - 2025-07-12 00:00:00 点击率:次大家好,又见面了,我是你们的朋友全栈君。
在之前的博客中,我们已经完成了一个简单的插件和测试程序的开发,但这些插件和应用是独立的工程。在实际的应用开发中,需要将相关的库和头文件整合到一个工程中,如下图所示,这样不仅方便调试和开发,还为创建跨平台工程提供了便利。
本节我们将创建一个示例工程,工程文件中包含应用程序以及要使用的各个插件,同时将各个平台编译后的ctk插件库文件也整合到一起。目前支持以下三个平台:
| 系统 | CPU | 编译器 | 说明 |
|---|---|---|---|
| windows | x86_64 | msvc | 64位系统 |
| linux | x86_64 | gcc | 64位系统 |
| linux | arm64 | gcc | 64位系统 |
未来我们计划增加windows-mingw和linux-arm32两个平台的支持。接下来,让我们简单介绍一下工程的实现。
-
工程创建
打开Qt Creator,选择文件 -> 新建文件或项目 -> 其他项目 -> Empty qmake Project,创建一个空的qmake工程,这里命名为
CtkpluginProj。通过文件浏览器进入该工程目录,新建三个目录,分别命名为
application,plugin-*,plugindepends。其中application目录用于存放应用程序,plugin-*为创建的一个插件示例,plugindepends用来存放ctk库文件。目录创建完成后如下图所示,这里插件命名为appinfo,即一个用于获取应用信息的插件。
1.1 plugindepends文件拷贝
plugindepends目录下存放ctk库的头文件及其编译生成的库文件。首先将ctk源码目录中的Libs/Core和Libs/PluginFramework两个目录拷贝到plugindepends目录下,core目录和pluginframework目录中存放着插件与应用程序编译所依赖的头文件,同时需要将编译生成的两个头文件也拷贝过来,分别是ctkCoreExport.h和ctkPluginFrameworkExport.h,它们分别位于CTK-build/Libs/Core和CTK-build/Libs/PluginFramework目录下。
以上步骤仅拷贝所需的头文件,接下来开始拷贝编译ctk后生成的库文件。为了支持跨平台,这里为每个平台各创建一个目录,并将相应的库文件拷贝进去。目前在windows-x64、linux-x64、linux-arm64三个平台下编译了ctk库,因此这里创建lib-linux-arm64-gcc、lib-linux-x64-gcc、lib-windows-x64-msvc三个目录。创建完成后如下图所示。
在linux和windows平台下需要拷贝的ctk库文件列表如下图所示。
最后创建一个Plugindepends.pri文件,用于添加qt工程中的头文件与库文件路径描述,文件内容如下。
INCLUDEPATH += $$PWD/../plugindepends/core/ \
$$PWD/../plugindepends/pluginframework/ \
$$PWD/../plugindepends/
win32-msvc*{ # for windows visual studio 2015 x64 msvc compiler
equals(QT_ARCH, x86_64): LIBS += -L$$PWD/../plugindepends/lib-windows-x64-msvc/ -lCTKCore -lCTKPluginFramework
}
win32-g++{ # for mingw x64 compiler
equals(QT_ARCH, x86_64): LIBS += -L$$PWD/../plugindepends/lib-windows-x64-mingw/ -lCTKCore -lCTKPluginFramework
}
linux{ # for linux gcc x64 compiler
equals(QT_ARCH, x86_64): LIBS += -L$$PWD/../plugindepends/lib-linux-x64-gcc/ -lCTKCore -lCTKPluginFramework
for linux gcc arm64 compiler
equals(QT_ARCH, arm64): LIBS += -L$$PWD/../plugindepends/lib-linux-arm64-gcc/ -lCTKCore -lCTKPluginFramework
}
1.2 创建第一个插件
第一个插件示例的功能是在运行时打印应用程序信息,其目录为plugin-appinfo。首先进入该目录,创建一个plugin-appinfo.pro文件,并填写以下内容。
QT += core
QT -= guiTARGET = plugin-appinfo
TEMPLATE = lib
CONFIG += plugin
include($$PWD/../plugindepends/Plugindepends.pri)
此时可以回到Qt Creator工具,修改工程文件CtkpluginProj.pro,添加以下内容。
TEMPLATE = subdirs
SUBDIRS += \
plugin-appinfo/plugin-appinfo.proCONFIG += ordered
保存CtkpluginProj.pro文件后,工程界面如下图所示。
此时右键点击plugin-appinfo,选择Add new,添加一个C++类,类名可以随意设置,这里命名为QPluginActivator,代码如下。
/* qpluginactivator.h ***/ifndef QPLUGINACTIVATOR_H
define QPLUGINACTIVATOR_H
include
include "ctkPluginActivator.h"
include "ctkPluginContext.h"
class QPluginActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "appinfo")
Q_INTERFACES(ctkPluginActivator)
public:
QPluginActivator();
void start(ctkPluginContext context);
void stop(ctkPluginContext context);
};
endif // QPLUGINACTIVATOR_H
/* qpluginactivator.cpp ***/
include "qpluginactivator.h"
include
include
QPluginActivator::QPluginActivator()
{
}
void QPluginActivator::start(ctkPluginContext *)
{
qDebug() << QCoreApplication::applicationName();
qDebug() << QCoreApplication::applicationFilePath();
}
void QPluginActivator::stop(ctkPluginContext *)
{
qDebug() << "Plugin stopped";
}
然后新建资源文件,添加前缀/plugin-appinfo/META-INF,并在资源文件中创建MANIFEST.MF插件清单文件。创建完成后,工程界面如下图所示。
1.3 创建第二个插件
第二个插件的创建就比较简单了,直接拷贝第一个插件的目录,进行一些简单修改即可。这里第二个示例插件命名为sysinfo,即加载插件时打印系统信息。首先通过文件浏览器进入到工程目录,拷贝plugin-appinfo插件目录为plugin-sysinfo,然后更改plugin-sysinfo目录下的plugin-appinfo.pro文件为plugin-sysinfo.pro,最后更改plugin-sysinfo.pro文件中的TARGET = plugin-sysinfo。
接下来再次回到Qt Creator,修改工程文件CtkpluginProj.pro,在其SUBDIRS项添加一行plugin-sysinfo/plugin-sysinfo.pro,然后工程界面如下图所示。
需要注意的是要修改资源文件resource.qrc的前缀,改成/plugin-sysinfo/META-INF,另外在qpluginactivator.cpp中根据需要更改插件功能,MANIFEST.MF清单文件中插件名称和版本号也可以重新设置。
1.4 创建应用程序
插件是为应用程序服务的,这里需要一个可执行程序来加载插件,从而调用插件的功能。首先进入工程的application目录,创建一个Application.pro文件,内容如下。
QT -= gui
CONFIG += console
CONFIG -= app_bundleinclude($$PWD/../plugindepends/Plugindepends.pri)
然后再次回到Qt Creator,修改工程文件CtkpluginProj.pro,在其SUBDIRS项添加一行application/Application.pro,然后工程界面如下图所示。
右键点击application,选择Add new,添加一个C++源文件,命名为main.cpp,其代码如下。
#include include
include
include
include
include
include
if defined(WIN32)
QString static appinfoPlugin_filePath = "../plugin-appinfo/debug/plugin-appinfo.dll";
QString static sysinfoPlugin_filePath = "../plugin-sysinf
o/debug/plugin-sysinfo.dll";
else
#ifdef __linux__
QString static appinfoPlugin_filePath = "../plugin-appinfo/libplugin-appinfo.so";
QString static sysinfoPlugin_filePath = "../plugin-sysinfo/libplugin-sysinfo.so";
#endif
endif
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ctkPluginFrameworkFactory frameworkFactory;
QSharedPointer framework = frameworkFactory.getFramework();
// 初始化并启动插件框架
try {
framework-youjiankuohaophpcninit();
framework-youjiankuohaophpcnstart();
QSharedPointerzuojiankuohaophpcnctkPluginContextyoujiankuohaophpcn pluginContext = framework-youjiankuohaophpcngetPluginContext();
// 安装并启动插件appinfo
try {
// 安装插件
QSharedPointerzuojiankuohaophpcnctkPluginyoujiankuohaophpcn plugin = pluginContext-youjiankuohaophpcninstallPlugin(QUrl::fromLocalFile(appinfoPlugin_filePath));
qDebug() zuojiankuohaophpcnzuojiankuohaophpcn QString("Installed plugin: %1 version %2").arg(plugin-youjiankuohaophpcngetSymbolicName()).arg(plugin-youjiankuohaophpcngetVersion().toString());
// 启动插件
plugin-youjiankuohaophpcnstart(ctkPlugin::START_TRANSIENT);
} catch (const ctkPluginException &e) {
qDebug() zuojiankuohaophpcnzuojiankuohaophpcn "Error installing appinfo plugin:" zuojiankuohaophpcnzuojiankuohaophpcn e.what();
}
// 安装并启动插件sysinfo
try {
// 安装插件
QSharedPointerzuojiankuohaophpcnctkPluginyoujiankuohaophpcn plugin = pluginContext-youjiankuohaophpcninstallPlugin(QUrl::fromLocalFile(sysinfoPlugin_filePath));
qDebug() zuojiankuohaophpcnzuojiankuohaophpcn QString("Installed plugin: %1 version %2").arg(plugin-youjiankuohaophpcngetSymbolicName()).arg(plugin-youjiankuohaophpcngetVersion().toString());
// 启动插件
plugin-youjiankuohaophpcnstart(ctkPlugin::START_TRANSIENT);
} catch (const ctkPluginException &e) {
qDebug() zuojiankuohaophpcnzuojiankuohaophpcn "Error installing sysinfo plugin:" zuojiankuohaophpcnzuojiankuohaophpcn e.what();
}
} catch (const ctkPluginException &e) {
qDebug() zuojiankuohaophpcnzuojiankuohaophpcn "Error starting plugin framework:" zuojiankuohaophpcnzuojiankuohaophpcn e.what();
}
return a.exec();}
-
运行应用
在Qt Creator软件中,点击绿色三角的运行键,开始编译运行工程,它会自动先编译插件,最后编译运行应用程序。windows-msvc环境下编译运行结果如下图所示。
linux-x86_64环境下编译运行结果如下图所示。
linux-arm64环境下编译运行结果如下图所示。
最后需要指出的是,这样编写工程的好处在于,迁移工程到一个已支持的平台上,不需要再先下载并编译配置CTK库,直接将整个工程代码拷贝到平台上编译运行即可,可以把精力集中在开发插件及应用程序上。
整个工程代码我已上传到csdn资源-12075076,欢迎下载并编译验证。
发布者:全栈程序员栈长,转载请注明出处:https://www./link/cd49f7f7616e5661b97901dc688b4385 原文链接:https://www./link/c8377ad2a50fb65de28b11cfc628d75c
# linux
# windows
# 浏览器
# 工具
# ai
# c++
# red
# qt
# html
# Resource
# char
# int
# 栈
# https
# 应用开发
# 所示
# 如下图
# 应用程序
# 命名为
# 创建一个
# 头文件
# 第一个
# 第二个
# 的是
# 目录下
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
如何快速生成专业多端适配建站电话?
手机软键盘弹出时影响布局的解决方法
怎么用AI帮你为初创公司进行市场定位分析?
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
公司网站制作价格怎么算,公司办个官网需要多少钱?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
微信小程序 wx.uploadFile无法上传解决办法
Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明
海南网站制作公司有哪些,海口网是哪家的?
如何在企业微信快速生成手机电脑官网?
非常酷的网站设计制作软件,酷培ai教育官方网站?
利用vue写todolist单页应用
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
高端企业智能建站程序:SEO优化与响应式模板定制开发
无锡营销型网站制作公司,无锡网选车牌流程?
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
历史网站制作软件,华为如何找回被删除的网站?
如何为不同团队 ID 动态生成多个非值班状态按钮
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
魔毅自助建站系统:模板定制与SEO优化一键生成指南
如何确保西部建站助手FTP传输的安全性?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
Laravel Docker环境搭建教程_Laravel Sail使用指南
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
phpredis提高消息队列的实时性方法(推荐)
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
七夕网站制作视频,七夕大促活动怎么报名?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
大学网站设计制作软件有哪些,如何将网站制作成自己app?
Laravel定时任务怎么设置_Laravel Crontab调度器配置
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
Laravel怎么为数据库表字段添加索引以优化查询
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
如何在IIS7上新建站点并设置安全权限?
Laravel如何使用Livewire构建动态组件?(入门代码)
Python文件流缓冲机制_IO性能解析【教程】
昵图网官网入口 昵图网素材平台官方入口
LinuxCD持续部署教程_自动发布与回滚机制
网站制作免费,什么网站能看正片电影?
如何用已有域名快速搭建网站?
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
Java垃圾回收器的方法和原理总结


o/debug/plugin-sysinfo.dll";