简述

在 Windows 中,有动态链接库(DLL - Dynamic Link Library);在 Linux 中,有共享库(Shared Library),它们是相同的!

由于平台和编译器的差异,输出的库文件也不同:

  • 在 Windows 中,MinGW 将输出 .a 和 .dll;MSVC 将输出 .lib 和 .dll。
  • 在 Linux 中,MinGW 将输出 .so、.so.1、.so.1.0 和 .so.1.0.0 - .lib
    .a 和 .so 是导入库,它们有助于将我们的代码链接到库中,并且在构建文件时需要。

创建共享库

要创建一个共享库,需要执行以下几个步骤:
文件 -> 新建文件或项目,选择:Library -> C++ 库:

- 选择“共享库”,然后输入“名称”(这里以 SharedLib 为例),并选择“创建路径”:

注意: “类型”下拉列表中有三个选项,分别是:共享库、静态链接库、Qt Plugin(Qt 插件)。

  • 选择一个适当的“构建套件”
  • 选择需要的模块(默认勾选“QtCore”,如果需要其他模块,请自行勾选。例- 如:界面需要依赖 QtWidgets)。
  • 执行要创建的源码文件的基本信息(默认即可)
  • 完成向导

项目文件

在项目创建完成之后,Qt Creator 会帮我们生成一系列相关文件,目录结构如下:

查看 .pro,并对其稍作修改:

TARGET = SharedLib# 新增部分
CONFIG += debug_and_release
CONFIG(debug, debug|release) {
    unix: TARGET = $$join(TARGET,,,_debug)
    else: TARGET = $$join(TARGET,,,d)
}TEMPLATE = lib
DEFINES += SHAREDLIB_LIBRARY
  • TARGET:指定库的名称
  • TEMPLATE:模板的意思,将其指定为 lib,是要告诉 qmake 我们需要生成的是一个库文件(app 为可执行程序)。
  • DEFINES:用于定义编译选项
  • CONFIG(新增部分):用于编译控制,区分 Debug 和 Release 版本的库名称(Debug 带 d,Release 不带)。

这里,同时出现了一个非常重要的文件 - {projectName}_global.h,这是 Qt Creator 帮我们创建的,内容如下:

#ifndef SHAREDLIB_GLOBAL_H
#define SHAREDLIB_GLOBAL_H#include <QtCore/qglobal.h>#if defined(SHAREDLIB_LIBRARY)
#  define SHAREDLIBSHARED_EXPORT Q_DECL_EXPORT
#else
#  define SHAREDLIBSHARED_EXPORT Q_DECL_IMPORT
#endif#endif // SHAREDLIB_GLOBAL_H

符号 - 函数、变量或类 - 包含在供客户端(例如:应用程序或其他库)使用的共享库中,必须以一种特殊的方式标记。这些符号被称为公共符号,它们被导出或公开可见。

在编译共享库时,必须将其标记为导出。为了在客户端使用共享库,一些平台可能需要一个特殊的导入声明。

为此,Qt 提供了两个特殊的宏:

  • Q_DECL_EXPORT:当编译共享库时,必须将其添加到使用的符号声明。
  • Q_DECL_IMPORT:当编译一个(使用了该共享库)客户端时,必须将其添加到使用的符号声明。

所以,要确保正确的宏能够被调用(无论是编译共享库本身,还是在客户端使用共享库),通常通过添加一个特殊的头文件({projectName}_global.h)来解决,这就是 sharedlib_global.h 存在的原因。

生成共享库

可以看到,生成的库中只有一个简单的类定义。为了便于使用,为其添加一些简单的函数:

sharedlib.h 内容如下:

#ifndef SHAREDLIB_H
#define SHAREDLIB_H#include "sharedlib_global.h"SHAREDLIBSHARED_EXPORT int subtract(int x, int y);class SHAREDLIBSHARED_EXPORT SharedLib
{public:SharedLib();int add(int x, int y);
};#endif // SHAREDLIB_H

sharedlib.cpp 内容如下:

#include "sharedlib.h"int subtract(int x, int y)
{return x - y;
}SharedLib::SharedLib()
{
}int SharedLib::add(int x, int y)
{return x + y;
}

构建(不运行)项目,会生成相应的 .lib 和 .dll 文件。

  • 注意: Debug 版本(带 d)为 SharedLibd.lib 和 SharedLibd.dll,Release 版本(不带 d)为 SharedLib.lib 和 SharedLib.dll。

将应用程序与共享库链接

为了使用共享库,创建一个简单的客户端 - Qt Console Application,然后调用库中导出的符号,效果如下:

项目创建成功后,将刚才生成的共享库组织成以下结构:

一切准备就绪,到了最关键的时刻 - 添加和使用库:

  • 右键项目 -> 添加库:

  • 选择链接到的库类型,这里选“外部库”:

  • 指定链接库和包含目录、平台等选项:

这时,.pro 中会自动添加以下代码:

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/3rdparty/SharedLib/lib/ -lSharedLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/3rdparty/SharedLib/lib/ -lSharedLibdINCLUDEPATH += $$PWD/3rdparty/SharedLib/include
DEPENDPATH += $$PWD/3rdparty/SharedLib/include
  • $$PWD 用于指定包含 .pro 文件的目录的完整路径
  • INCLUDEPATH - 指定编译项目时应该被搜索的 #include 目录
  • LIBS - 指定链接到项目中的库列表

开始测试,main.cpp 内容如下:

#include <QCoreApplication>
#include <qDebug>
#include "sharedlib.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 测试库SharedLib lib;qDebug() << lib.add(2, 3);qDebug() << subtract(5, 2);return a.exec();
}

OK,运行程序,效果如上所示。

注意: 在运行程序时,需要将对应的 dll(Debug 为 SharedLibd.dll,Release 为 SharedLib.dll) 拷贝到和可执行程序同一级目录下,否则会出错。

更多参考

Qt使用第三方库


版权所有:一去丶二三里
原文出处:http://blog.csdn.net/liang19890820

Qt之创建并使用共享库相关推荐

  1. Qt文档阅读笔记-共享库的创建与调用

    使用共享库的符号 这个符号可以作用在变量.类.函数中,并且这些都可以被调用端使用. 在编译共享库中,需要使用export符号.在使用端调用的时候使用import符号. 这里是本人从文档中记录的笔记,大 ...

  2. visual studio 2017 创建 android 本地共享库(.so) 并从 C# android 项目中调用

    Developing Xamarin Android Native Applications ★★★★★ ★★★★ ★★★ ★★ ★ February 23, 2015 by Ankit Asthan ...

  3. Linux 共享库简介(怎样创建共享库)

    前言 0x1 什么是共享库 0x2 共享库在文件系统中的位置 0x3 使用 ldconfig 命令 0x4 使用非标准库位置 0x5 示例(如何创建一个共享库) 前言 一个库文件由多个不同的目标文件填 ...

  4. 程序员的自我修养--链接、装载与库笔记:Linux共享库的组织

    共享库(Shared Library)概念:其实从文件结构上来讲,共享库和共享对象没什么区别,Linux下的共享库就是普通的ELF共享对象.由于共享对象可以被各个程序之间共享,所以它也就成为了库的很好 ...

  5. arm linux 加载.a,如何将libc.a链接到arm-linux中的共享库中使用arm-none-linux-gnueabi-gcc...

    在一个项目中,我的同事创建了一个静态库,例如liba.a,它与app链接. 在liba.a中,他将libc malloc()覆盖为其所有者版本. 我创建了一个共享库libs.so,它也与app链接. ...

  6. linux中安装,编译时调用,运行时调用,更新共享库

    一 创建并编译共享库 动态链接库一般以lib开头,形如libmymodule.so.1.0.0. 后面跟的三个版本号,从左到右的含义为: (1) 大版本号,当接口变得和之前不兼容,则新增一个大版本号. ...

  7. C语言的静态库与共享库

    文章目录 1.库的概念 2.静态库 2-1 静态库的概念 2-2 静态库的创建 2-2-1 静态库创建的命令 2-2-2 静态库创建的准备工作 2-2-3 创建静态库的例子 2-3 静态库的使用 2- ...

  8. Linux 环境编程 day01 Linux系统介绍、GNU编译工具、静态/共享库、环境变量表

    Linux 环境编程 day01 Linux系统介绍.GNU编译工具.静态/动态库.环境变量表 学习Linux环境编程的原因 UNIX系统介绍 Linux系统介绍 GNU工程 POSIX标准 GNU通 ...

  9. 【读书笔记】【程序员的自我修养 -- 链接、装载与库(二)】进程虚拟地址空间、装载与动态链接、GOT、全局符号表、共享库的组织、DLL、C++与动态链接

    文章目录 前言 介绍 可执行文件的装载与进程 进程虚拟地址空间 装载方式 操作系统对可执行文件的装载 进程虚存空间分布 ELF文件的链接视图和执行视图 堆和栈 Linux 内核装载ELF & ...

最新文章

  1. php5.3中的safe_mod与magic_quotes_gpc
  2. 普通程序员如何转向AI方向(转)
  3. ThinkPHP实现定时执行任务的两种方法 - 博客频道 - CSDN.NET
  4. python所有函数用法_Python函数使用方法(高级用法)
  5. Android Studio 打包 V1 V2 签名
  6. 我的小型网站搜索分词中遇到的问题
  7. NYOJ-99 单词拼接(欧拉+回溯)
  8. IntelliJ IDEA中文乱码问题
  9. python句柄无效_subprocess.Popen 运行windows命令出现“句柄无效”报错的解决方法
  10. android 升级数据库 修改表结构
  11. python第三方库tkinter之Label控件和Button控件
  12. Qt5.4生成安装包过程
  13. C#ToString() 格式化数值
  14. 电脑亮度多少对眼睛好_黄江办公文员学费大概是多少,黄江附近哪个电脑学校比较好一点...
  15. 【爬虫学习笔记day51】6.1. scrapy-redis的官方文档源码分析参考:Connection
  16. 轻量级深度神经网络推理引擎——阿里巴巴的 MNN
  17. 分享两种证件照换背景方法,轻松把照片底色变白
  18. 使用 ROT13 算法加密解密数据
  19. 图像处理之基础---去污算法
  20. jq实现多开关效果互不影响

热门文章

  1. Spring-视图解析
  2. ArcGIS鼠标滚轮方向之ArcMap篇
  3. python使用ElementTree解析XML文件
  4. String与Date转换
  5. 软件工程第三次作业-功能测试
  6. ストアドプロシージャ(存储过程)
  7. HDU 2899 三分
  8. 问模板函数、函数模板,模板类、类模板的区别的问题?
  9. chrome浏览器中遇到bug【Error in event handler: TypeError: Cannot read property 'name' of undefined】
  10. k8s控制器:Job和CronJob