Qt 动态链接库

Qt 动态链接库

新知笔记 📅 2020-09-02 ⏱ 约 9 分钟
✦
AI 摘要AI Abstract
  • 静态链接库将函数代码直接嵌入可执行文件,导致内存中存在多份拷贝,扩展名为.lib(Windows)或.a(Linux)。
  • 动态链接库在运行时加载,多个程序共享同一份内存中的代码,扩展名为.dll(Windows)或.so(Linux),提升…
  • 使用Qt Creator创建C++库项目,通过Q_DECL_EXPORT/IMPORT宏实现跨平台的动态库导出与导入机…
  • 调用动态库需配置.pro文件引入库路径,并将.dll文件置于可执行文件同级目录以确保运行时正确加载。

近期,在学完 Qt 编程的一些基础知识后,我逐渐往更深层次进发。今天,要记录的是,Qt 框架中动态链接库相关的知识。

有动态链接库是就会有静态链接库,来都来了,肯定是要一次性都解决的。先来看看这两类链接库的区别。

静态链接库(Static-link library)就是把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分的库。换言之,函数和过程的代码就在主程序的 .exe 文件中,该文件包含了运行时所需的全部代码。当多个程序调用相同的函数是,内存中会存在这个函数的多个拷贝。在 Windows 操作系统中,静态链接库对应的后缀名为 .lib, 在 Linux 操作系统中,静态链接库对应的后缀名为 .a 。

动态链接库(Dynamic-link library)是微软公司在 Windows 操作系统中实现共享库概念的一种实现方式,后被很多操作系统作为参考,从而使其有了更大的发展。在 Windows 操作系统中,静态链接库对应的后缀名为 .dll , 在 Linux 操作系统中,动态链接库对应的后缀名为 .so。

在 Windows 操作戏台中,所谓动态链接,就是把一些经常会共享的代码(静态链接的 OBJ 程序库)制作成 DLL 档,当可执行文件调用到 DLL 档内的函数时, Windows 操作系统才会把 DLL 档加载到内存中, DLL 档本身的结构就是可执行档,当程序有需求时函数才进行链接。一般情况下,如果一个应用使用了动态链接库, Win32 系统保证内存中只有DLL的一份复制品。

说完动态链接库与静态链接库的区别,不能光纸上谈兵,应该动手来个实例。不如就动手实现一个简易计算的动态库吧。

编写动态库

1.建立库文件

首先打开 Qt Creator 的新建对话窗口,找到 Library,点击创建 C++ Library。 image-20200902140109533

给定一个名字,然后点击下一步 ,在选择 Qt module 时,选择 Core模块。

image-20200902140458089

接着,勾选一个编译环境。

image-20200902140557133

2. 编写库函数代码

compute.pro

QT -= gui
 
TEMPLATE = lib
DEFINES += COMPUTE_LIBRARY
 
CONFIG += c++11
 
DEFINES += QT_DEPRECATED_WARNINGS
 
SOURCES += \
    compute.cpp
 
HEADERS += \
    compute_global.h \
    compute.h
 
unix {
    target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target

compute.h

/***************************************************
 *
 * @file       compute.h
 * @version    1.0
 *
 * @author     AmosWu
 * @date       2020/09/02
 * @history    
 ***************************************************/
#ifndef COMPUTE_H
#define COMPUTE_H
 
#include "compute_global.h"
 
class COMPUTE_EXPORT Compute
{
public:
    Compute();
    int sum(int x, int y);
    int diff(int x, int y);
    double prod(double a, double b);
    double divi(double a, double b);
};
 
#endif // COMPUTE_H
 

compute_global.h

#ifndef COMPUTE_GLOBAL_H
#define COMPUTE_GLOBAL_H
 
#include <QtCore/qglobal.h>
 
#if defined(COMPUTE_LIBRARY)
#  define COMPUTE_EXPORT Q_DECL_EXPORT
#else
#  define COMPUTE_EXPORT Q_DECL_IMPORT
#endif
 
#endif // COMPUTE_GLOBAL_H

compute.cpp

/***************************************************
 *
 * @file       compute.cpp
 * @version    1.0
 *
 * @author     AmosWu
 * @date       2020/09/02
 * @history    
 ***************************************************/
#include "compute.h"
 
Compute::Compute()
{
}
 
int Compute::sum(int x, int y)
{
    return x + y;
}
 
int Compute::diff(int x, int y)
{
    return x - y;
}
 
double Compute::prod(double a, double b)
{
    return a * b;
}
 
double Compute::divi(double a, double b)
{
    if(b > 0)
        {
            return a / b;
        }
    else
        {
            return 999.99;
        }
}

在编写完上述代码后,我们调试一下,或者构建不运行,就会在对应文件夹看到已经生成 .lib 和 .dll等库文件了。

image-20200902145444525

调用动态库

1.创建项目

这里就不再赘述了了了了了了了了了了

2.拷贝头文件

将头文件拷贝到应用工程的目录下,对于大型项目要单独建立文件夹,这里是一个小 Demo ,我就直接放到根目录下了。

image-20200910124324053

3. 引入dll

.pro

LIBS += ‪-LE:/Qt_code/build-compute-Desktop_Qt_5_14_0_MinGW_64_bit-Debug/compute.dll

main.cpp

#include "widget.h"
#include "compute.h"
#include <QApplication>
#include <QDebug>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setWindowTitle(QStringLiteral("简易计算器"));
 
    Compute cal;
    qDebug() << "Result:" <<  cal.sum(2, 10) << endl;
 
    w.show();
    return a.exec();
}

4.拷贝 .dll 到编译好的程序 .exe 同级目录下

image-20200910124645704

5. 调试运行

image-20200910123826075

此篇仅做动态链接库知识基础,还有更多高级应用,请移步搜索引擎~

评论