VS2019+QT实现qt项目(带界面)封装为dll并在其它qt项目被调用(带界面)(C++)

发布于:2025-06-27 ⋅ 阅读:(18) ⋅ 点赞:(0)

前言:

        在编写的QT项目需要与他人协作开发时,我们会希望将程序作成一个“输入->交互处理->输出”的功能模块,但是QT带界面的程序不像C++函数那样简单封装调用,因此实现对QT程序的封装调用成了笔者困扰许久的问题,在此过程中尝试了许多方法似乎都有大大小小的报错,最后在友人帮助下实现了该功能,具体如下。

注意:

        下述内容中,“Your_QT_Project”指的是需要做成动态库(dll)的QT项目的名称,请您在参考代码时替换此处名称;“Your_QT_Project_Demo”指的是用来调用动态库(dll)的QT项目的名称,请您在参考代码时替换此处名称。

目录

一、将QT项目封装为DLL

1、Class类的修改

2、定义DLL的输入(接口)内容

        (1)创建结构体作为传入参数

        (2)将结构体传入到程序

        (3)结构体在qt程序中作为传参使用

3、定义DLL的输出(接口)内容

        (1)创建结构体作为传出参数

        (2)定义公共函数返回结构体

4、项目属性配置类型的修改(生成为dll)

5、屏蔽main函数

6、生成dll和lib

二、使用封装好的DLL(包括dll的界面嵌入到当前QT界面中)

1、环境配置

        (1)需要配置的文件

        (2)项目属性配置

        (3)头文件导入

2、DLL输入接口的使用与界面嵌入

        (1)对封装动态库的类实例化 

        (2)初始化传入参数的结构体并显示封装动态库的界面

3、DLL输出内容的获取


一、将QT项目封装为DLL

步骤如下:

1、Class类的修改

        打开QT项目的.h文件,找到class部分,此处原先为:

class Your_QT_Project : public QMainWindow

        改为:

class Q_DECL_EXPORT Your_QT_Project : public QMainWindow

此处新增了“Q_DECL_EXPORT”,原因是:

QT使用以下两个宏来实现符号(函数或全局变量/对象)的导出和导入(跨平台不能用def文件了):
Q_DECL_EXPORT   // 必须添加到符号声明中(共享库项目)  
Q_DECL_IMPORT   // 必须添加到符号声明中(使用共享库的客户项目) 
QT使用 QLibrary 类实现共享库的动态加载,即在运行时决定加载那个DLL程序,插件机制使用。

2、定义DLL的输入(接口)内容

        (1)创建结构体作为传入参数

        考虑到输入内容的多样性,此处我们使用结构体作为输入内容传参

        打开QT项目的.h文件,在.h文件中定义结构体:

struct Input_InitParams
{
    std::string                data_input;
    std::vector<double>        point_input;
    bool                       flag_input;
}

        (2)将结构体传入到程序

        打开QT项目的.h文件,在qt的class类中找到如下内容:

public:
    Your_QT_Project(QWidget* parent = nullptr);

        上述内容改为:

public:
    Your_QT_Project(Input_InitParams initParams,QWidget* parent = nullptr);

        (3)结构体在qt程序中作为传参使用

        打开QT项目的.cpp文件,在开头部分找到如下内容:

Your_QT_Project::Your_QT_Project(QWidget *parent)
    : QMainWindow(parent),
    ui(new Ui::Your_QT_ProjectClass)
{
    //....
}

        上述内容改为:

Your_QT_Project::Your_QT_Project(Input_InitParams initParams,QWidget *parent)
    : QMainWindow(parent),
    ui(new Ui::Your_QT_ProjectClass)
{
    //....
    //这里就可以直接使用initParams这个结构体作为传入参数了
}

3、定义DLL的输出(接口)内容

        (1)创建结构体作为传出参数

        考虑到输出内容的多样性,此处我们使用结构体作为输出内容

        打开QT项目的.h文件,在.h文件中定义结构体:

struct Output_GetData
{
    std::string                data_output;
    std::vector<double>        point_output;
    bool                       flag_output;
}

        (2)定义公共函数返回结构体

打开QT项目的.h文件,在class类中添加公共函数用于返回输出的结构体:

public:
    Output_GetData GetOutPutData();

打开QT项目的.h文件,在class类中添加结构体的定义变量:

private:
    Output_GetData outputData;

打开QT项目的.cpp文件,实现GetOutPutData函数:

Output_GetData Your_QT_Project::GetOutPutData()
{
    outputData.data_output = "输出参数data_output";
    outputData.point_output.pushback(123);
    outputData.flag_output = true;
    return outputData;
}

        实现上述步骤后,就可以通过GetOutPutData函数直接获取到程序返回的内容。

4、项目属性配置类型的修改(生成为dll)

        在vs的右侧资源管理器选择qt项目,右击,选择“属性”,选择“常规”->"配置类型"->"动态库.dll",应用并确认。

5、屏蔽main函数

        注释qt项目中main.cpp中的所有内容,目的是去除int main()的启动。

6、生成dll和lib

        在vs的右侧资源管理器选择qt项目,右击,选择“重新生成”。至此就完成了QT项目的动态库封装全部内容。

二、使用封装好的DLL(包括dll的界面嵌入到当前QT界面中)

步骤如下:

1、环境配置

        (1)需要配置的文件

        打开上述生成dll的qt项目的x64/Release或者x64/Debug(你用什么模式生成的就打开哪个)目录,找到刚刚生成的Your_QT_Project.dllYour_QT_Project.lib

        打开上述生成dll的qt项目根目录,找到Your_QT_Project.h文件(上述编辑过的qt项目的.h文件);

        (2)项目属性配置

        在Your_QT_Project_Demo项目(需要使用这个qt动态库的qt项目)属性中,分别配置好包含目录(Your_QT_Project.h所在目录)、链接器-附加库目录(Your_QT_Project.lib所在目录)、链接器-附加依赖项(把Your_QT_Project.lib这个名字放进去);

        (3)头文件导入

          在Your_QT_Project_Demo项目右侧“解决方案资源管理器”处右击项目头文件目录“Header Files”,选择添加现有项,添加Your_QT_Project.h

        在Your_QT_Project_Demo项目的头文件在Your_QT_Project_Demo.h的开头添加:

#include "Your_QT_Project.h"

2、DLL输入接口的使用与界面嵌入

        (1)对封装动态库的类实例化 

        在Your_QT_Project_Demo项目的.h文件,在class类中添加如下内容:

private:
    Your_QT_Project* your_qt_project;

        (2)初始化传入参数的结构体并显示封装动态库的界面

        在Your_QT_Project_Demo项目的.cpp文件中,在程序初始化部分/需要用到封装的qt动态库内容部分添加如下代码:

Input_InitParams input_init;
input_init.data_input = "输入参数";
input_init.point_input.pushback(123);
input_init.flag_input = true;

your_qt_project = new Your_QT_Project(input_init);//传入结构体-作为传入参数
ui->horizontalLayout->addWidget(your_qt_project);//显示UI
//这里的horizontalLayout是一个自己在ui添加的组件,也可以是tabwidget之类的

3、DLL输出内容的获取

Output_GetData output_data = your_qt_project->GetOutPutData();

此处通过公有的GetOutPutData()函数的返回值得到了封装动态库的返回内容(返回的结构体)。

后记:

        由于特殊原因,上述内容为笔者在网页端编写,如有错误内容请及时联系,感谢您的指正!

        随着国产人工智能deepseek的崛起,查阅代码问题变得越来越容易便捷了,平时遇到的小问题或者简单的算法都可以让AI实现,属实是方便了许多,以至于往年一个月更新多篇博客的笔者到了如今几个月才想“被迫”更新一下。

        写博客是一种将已学知识的归纳整理,从而形成体系化的学习流程;尤其到了工作中后,学习往往是零碎化的,需要开发什么就学习什么,知识杂七杂八,项目需求更是复杂多样,保不准半年不到就忘光了过去所写的代码。因此将开发过程中遇到的难点、繁琐点、常用点、易错点记录下来就显得尤为重要了,更何况还可以分享帮助更多的开发者避开陷阱、共同进步。


网站公告

今日签到

点亮在社区的每一天
去签到