项目结构
整个工程由一个主程序构成和一个模块构成(dll)。整个工程的结构目录如下
Define.pri
MyProject.pro
MyProject.pro.user
+---bin
+---MainProgram
main.cpp
MainProgram.pro
MainProgram.pro.user
widget.cpp
widget.h
widget.ui
+---MathDll
MathDll.pro
MathDll.pro.user
MyMath.cpp
MyMath.h
qmake文件介绍
1 MyProject.pro
TEMPLATE = subdirs #多工程项目
CONFIG += ordered #指定编译顺序
SUBDIRS = MathDll \ #模块(dll)
MainProgram #主工程
2 Define.pri
win32 {
CONFIG(release, debug|release){
contains(QT_ARCH, i386) {
BIN_PATH=release_x86_
} else {
BIN_PATH=release_x64_
}
} else {
contains(QT_ARCH, i386) {
BIN_PATH=debug_x86_
} else {
BIN_PATH=debug_x64_
}
}
}
DESTDIR = $$PWD/bin/$$BIN_PATH #生成的二进制文件(可执行文件或者库)的目标位置,放在pri文件中,在有pro文件包含这样就不用重复写
3 MathDll.pro
QT -= gui
TEMPLATE = lib
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked 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
DEFINES += MATHDLL_LIBRARY #使用预定义来控制是导出函数符号到dll还是导出dll中的函数符号
# You can also make your code fail to compile if it uses 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
include($$PWD/../Define.pri) #引入pri文件
SOURCES += \
MyMath.cpp \
MyMath.h
#拷贝头文件到指定目录,以便其它程序能够使用该dll
QMAKE_POST_LINK += xcopy /y/F \"$$PWD/MyMath.h\" \"$$PWD/../bin/includePath\\\" $$escape_expand(\\n\\t)
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
4 MainProgram.pro
#-------------------------------------------------
#
# Project created by QtCreator 2023-12-09T17:29:33
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = MainProgram
TEMPLATE = app
# 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
include($$PWD/../Define.pri) #引入pri文件
LIBS += -L$$PWD/../bin/$$BIN_PATH #设置搜索链接动态库的目录
CONFIG += c++11
INCLUDEPATH += $$PWD/../bin/includePath #设置搜索头文件目录
LIBS += -lMathDll #链接库文件
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
注意 :
LIBS += -L$$PWD/../bin/$$BIN_PATH
这句话是很重要的,在程序编译链接时会使用到动态库的 lib
文件,用于生成程序。而默认链接的位置是 MainProgram
目录下,如果没有该语句就会提示找不到 MathDll.lib
文件,可执行程序生成失败。
源文件分析
1 MyMath.h
#ifndef MYMATH_H_
#define MYMATH_H_
//包含QObject才能识别 Q_DECL_EXPORT Q_DECL_IMPORT
#include <QObject>
//预定义来控制导入导出符号
#if defined (MATHDLL_LIBRARY)
#define MATHDLL_LIBRRY_EXPORT Q_DECL_EXPORT
#else
#define MATHDLL_LIBRRY_EXPORT Q_DECL_IMPORT
#endif
class MATHDLL_LIBRRY_EXPORT MyMath{
public:
MyMath();
~MyMath();
int add(int a, int b);
};
#endif
2 widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "MyMath.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
int a = ui->lineEdit->text().toInt();
int b = ui->lineEdit_2->text().toInt();
MyMath myMath;
int sum = myMath.add(a, b); //使用动态链接库中的函数
ui->label->setText(ui->label->text() + QString::number(sum));
}