文章目录
一、示例图
使用不同的编译模式编译,会在对应的编译目录下生成“TestDll”文件夹(在pro文件中添加“DESTDIR = ./TestDll”指定的生成目录),然后根据target指定(没有指定则默认和项目名一致)的名字生成对应的库名,如下图所示。
二、普通项目需要改造的内容
- 首先阐述一下此处的“普通项目”指的是通过Qt新建项目,可以直接运行的项目。
- 普通项目需要生成dll文件只需要在Qt的pro文件中将“TEMPLATE = app”更改为“TEMPLATE = lib“即可。
- 但是,通过第二点仅仅只能生成dll文件,若是要生成lib文件,则需要在外部类的声明位置使用Q_DECL_EXPORT/Q_DECL_IMPORT标记(当然 lib也可以通过 config += staticlib来生成,但是并不适用于此处)。
- Q_DECL_EXPORT,用于导出类或函数,使得在动态链接库时中可以使用这些类或函数。
- Q_DECL_IMPORT,用于导入类或函数,目的就是使用通过Q_DECL_EXPORT导出的类或函数。
三、源码(创建了一个TestDLL的项目,更改内容主要在pro文件和maindow.h文件)
TestDLL.pro
在pro文件中添加/更改的内容如下(注意下方的TEST_DLL_FLAG宏):
# 将原先的app更新为lib
TEMPLATE = lib
# 定义测试库标记(为明确当前为普通项目的标记)
DEFINES += TEST_DLL_FLAG
# 根据不同的编译模式生成不同的名字(通常来说debug模式下生成的文件以d结尾)
win32:CONFIG(release, debug|release): {
TARGET = TestDLL
}
else {
TARGET = TestDLLd
}
# 指定生成库的目录
DESTDIR = ./TestDll
完整内容如下:
#-------------------------------------------------
#
# Project created by QtCreator 2023-10-16T23:37:44
#
#-------------------------------------------------
QT += core gui
#生成DLL
TEMPLATE = lib
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# 定义测试库标记(为明确当前为普通项目的标记)
DEFINES += TEST_DLL_FLAG
# 根据不同的编译模式生成不同的名字(通常来说debug模式下生成的文件以d结尾)
win32:CONFIG(release, debug|release): {
TARGET = TestDLL
}
else {
TARGET = TestDLLd
}
# 指定生成库的目录
DESTDIR = ./TestDll
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${
TARGET}/bin
else: unix:!android: target.path = /opt/$${
TARGET}/bin
!isEmpty(target.path): INSTALLS += target
mainwindow.h
通过定义的TEST_DLL_FLAG宏区分是导出还是导入状态,当前为普通项目时,会识别到TEST_DLL_FLAG宏,则TEST_DLL_MODE 代表的内容为Q_DECL_EXPORT,反之为Q_DECL_IMPORT,正好对应导出和导入。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
//! 定义库模式宏,为区分到处和导入的模式情况
//! 通常来说,哪个类需要在库外调用在哪个类的定义前方添加模式宏即可
#ifdef TEST_DLL_FLAG
#define TEST_DLL_MODE Q_DECL_EXPORT
#else
#define TEST_DLL_MODE Q_DECL_IMPORT
#endif
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class TEST_DLL_MODE MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>35</pointsize>
</font>
</property>
<property name="text">
<string>测试dll项目</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
总结
普通项目生成DLL的内容到此结束,如何使用导出的dll和lib在下一篇文章体现。
相关文章
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
文章评论