qt子目录项工程模板及动态库二进制兼容测试实现
qt子目录项工程模板及动态库二进制兼容测试实现文章目录概述设计思路源代码解析MainWindowUI界面动态库函数调用class LeeWidget显式类隐式类函数实现class LeeLabel显式类隐式类结果概述本篇文章是在qtcreator源码学习的支线知识,主线在这里1,主要目的是两个:写一个qt subdir工程模板方便后续开发套用测试动态库二进制兼容设计思路设计思路是写一个qAppli
qt子目录项工程模板及动态库二进制兼容测试实现
概述
本篇文章是在qtcreator源码学习的支线知识,主线在这里1,主要目的是两个:
- 写一个qt subdir工程模板方便后续开发套用
- 测试动态库二进制兼容
设计思路
设计思路是写一个qApplication,调用两个库分别是LeeWidget和LeeLabel,LeeLabel是LeeWidget的子类,生成这两个动态库到指定目录。
由于LeeLabel是子类,理论上在不考虑二进制兼容时运行会出问题,通过d指针来实现兼容;
源代码解析
subdir子目录项结构如下图所示:

CONFIG += ordered的作用是按照顺序编译;
MainWindow
主工程的pro文件如下所示,突然发现LIBS好像有点重复不过没什么影响,对于CONFIG里几个参数说明查到一篇文章写得不错,附上链接Qt指定临时文件生成目录
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += debug_and_release warn_on plugin
TARGET = LeeMainWindow
TEMPLATE = app
CONFIG(debug, debug|release) {
DESTDIR = ../../bin/Debug$$arch
LIBS += -L../../bin/Debug$$arch
OBJECTS_DIR = ../../bin/Debug$$arch/$${TARGET}/obj
MOC_DIR = ../../bin/Debug$$arch/$${TARGET}/moc
RCC_DIR = ../../bin/Debug$$arch/$${TARGET}/rcc
UI_DIR = ../../bin/Debug$$arch/$${TARGET}/ui
} else {
DESTDIR = ../../bin/Release$$arch
LIBS += -L../../bin/Release$$arch
OBJECTS_DIR = ../../bin/Release$$arch/$${TARGET}/obj
MOC_DIR = ../../bin/Release$$arch/$${TARGET}/moc
RCC_DIR = ../../bin/Release$$arch/$${TARGET}/rcc
UI_DIR = ../../bin/Release$$arch/$${TARGET}/ui
}
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../LeeLabel/ -lLeeLabeld
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../LeeLabel/ -lLeeLabeld
else:unix: LIBS += -L$$OUT_PWD/../LeeLabel/ -lLeeLabeld
INCLUDEPATH += $$PWD/../LeeLabel
DEPENDPATH += $$PWD/../LeeLabel
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../LeeWidget/release/ -lLeeWidgetd
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../LeeWidget/debug/ -lLeeWidgetd
else:unix: LIBS += -L$$OUT_PWD/../LeeWidget/ -lLeeWidgetd
INCLUDEPATH += $$PWD/../LeeWidget
DEPENDPATH += $$PWD/../LeeWidget
UI界面
如下图所示,做了一个加减法计算接口。

动态库函数调用
void MainWindow::slot_CalculateButtonClick()
{
qreal result = 0;
qreal a = 0, b = 0;
a = ui->numA_LE->text().toDouble();
b = ui->numB_LE->text().toDouble();
if (ui->leeLabelPlus_RB->isChecked())
{
result = m_label->pluseTwo(a, b);
}
else if (ui->leeLabelMinus_RB->isChecked())
{
result = m_label->minusTwo(a, b);
}
else if (ui->leeWidgetPlus_RB->isChecked())
{
result = m_widget->pluseTwo(a, b);
}
ui->result_Label->setText(QString::number(result,'f', 2));
}
这一段就是核心代码了,调用动态库中的函数。
class LeeWidget
这是我使用d指针实现的一个类,该类是QObject的子类,pro文件如下所示:
QT += core
TEMPLATE = lib
DEFINES += LEEWIDGET_LIBRARY
CONFIG += c++11
TARGET = $$qtLibraryTarget($$TARGET)
#TARGET = LeeWidget
CONFIG(debug, debug|release) {
DESTDIR = ../../bin/Debug$$arch
LIBS += -L../../bin/Debug$$arch
OBJECTS_DIR = ../../bin/Debug$$arch/$${TARGET}/obj
MOC_DIR = ../../bin/Debug$$arch/$${TARGET}/moc
RCC_DIR = ../../bin/Debug$$arch/$${TARGET}/rcc
} else {
DESTDIR = ../../bin/Release$$arch
LIBS += -L../../bin/Release$$arch
OBJECTS_DIR = ../../bin/Release$$arch/$${TARGET}/obj
MOC_DIR = ../../bin/Release$$arch/$${TARGET}/moc
RCC_DIR = ../../bin/Release$$arch/$${TARGET}/rcc
}
SOURCES += \
leewidget.cpp
HEADERS += \
LeeWidget_global.h \
global.h \
leewidget.h \
leewidget_p.h
该类主要提供加法的接口,但加法函数的实际实现通过调用d指针指向的私有类对象函数实现。
显式类
/****************************************************************
Doc : leewidget.h
Author : BingLee
Date : 2020-12-07
Info : .
https://blog.csdn.net/Bing_Lee (C)All rights reserved.
******************************************************************/
#ifndef LEEWIDGET_H
#define LEEWIDGET_H
#include "LeeWidget_global.h"
#include <QObject>
class LeeWidgetPrivate;
class LEEWIDGET_EXPORT LeeWidget : public QObject
{
Q_OBJECT
public:
LeeWidget(QObject *parent = 0);
virtual ~LeeWidget();
qreal pluseTwo(qreal firstNum, qreal secondNum);
protected:
/*
该接口的主要作用是避免每有一个继承子类,就会为相应的LeeWidgetPrivate分配空间。
https://blog.csdn.net/Bing_Lee
*/
LeeWidget(LeeWidgetPrivate &d_ptr);
LeeWidgetPrivate *d;
};
#endif // LEEWIDGET_H
隐式类
/****************************************************************
Doc : LeeWidget_p.h
Author : BingLee
Date : 2020-12-07
Info : .
https://blog.csdn.net/Bing_Lee (C)All rights reserved.
******************************************************************/
#ifndef LEEWIDGET_P_H
#define LEEWIDGET_P_H
#include "leewidget.h"
class LeeWidgetPrivate
{
public:
LeeWidgetPrivate(LeeWidget *q_ptr)
: q(q_ptr)
{}
//这里是实际实现加法功能的函数。
qreal plusAandB(qreal a, qreal b);
protected:
LeeWidget *q;
};
#endif // LEEWIDGET_P_H
函数实现
#include "leewidget.h"
#include "LeeWidget_p.h"
LeeWidget::LeeWidget(QObject *parent)
: QObject(parent),
d(new LeeWidgetPrivate(this))
{
}
LeeWidget::~LeeWidget()
{
delete d;
}
qreal LeeWidget::pluseTwo(qreal firstNum, qreal secondNum)
{
return d->plusAandB(firstNum, secondNum);
}
LeeWidget::LeeWidget(LeeWidgetPrivate &d_ptr)
: d(&d_ptr)
{
}
qreal LeeWidgetPrivate::plusAandB(qreal a, qreal b)
{
return a+b;
}
class LeeLabel
显式类
/****************************************************************
Doc : leelabel.h
Author : BingLee
Date : 2020-12-07
Info : .
https://blog.csdn.net/Bing_Lee (C)All rights reserved.
******************************************************************/
#ifndef LEELABEL_H
#define LEELABEL_H
#include "LeeLabel_global.h"
#include "leewidget.h"
class LeeLabelPrivate;
class LEELABEL_EXPORT LeeLabel : public LeeWidget
{
Q_OBJECT
public:
LeeLabel();
qreal minusTwo(qreal firstNum, qreal secondNum);
protected:
LeeLabel(LeeLabelPrivate &d_ptr);
};
#endif // LEELABEL_H
隐式类
/****************************************************************
Doc : leelabel_p.h
Author : BingLee
Date : 2020-12-07
Info : .
https://blog.csdn.net/Bing_Lee (C)All rights reserved.
******************************************************************/
#ifndef LEELABEL_P_H
#define LEELABEL_P_H
#include "leelabel.h"
#include "LeeWidget_p.h"
class LeeLabelPrivate : public LeeWidgetPrivate
{
public:
LeeLabelPrivate()
: LeeWidgetPrivate(0)
{}
//这里是实际实现减法功能的函数。
qreal minusAandB(qreal a, qreal b);
QString m_name;
};
#endif // LEELABEL_P_H
结果
编译目录如下所示:

实现结果如下图所示:

二进制兼容测试初步试验没有出现兼容问题,后期用vs编译测试下。
如果喜欢本文,请帮忙给博主点赞、评论、关注三连哦~
源代码下载链接
-
我勒个去,竟然还没发那篇… TODO_后边写了替换下 ↩︎
更多推荐



所有评论(0)