说明

之前讨论的DLL的静态链接和动态连接都是基于 MSVC 编译器,但是 MinGW 似乎有另外一套类似但是不相同的机制。下文均在 windows 下使用 Qt Creator 中使用 MinGW 进行说明。

我们在新建库项目的时候有三种选项,如图所示:

三种类型分别是:共享库、静态链接库和Qt插件,之间区别以及和 MSVC 的库区别如下:

  1. 项目会根据类型不同生成 .dll 和 .a文件,这里的 .a 即类似 .lib,但是又不完全相同;
  2. 共享库 类似 msvc 的静态链接,构建最终生成 .a(类似.lib) 和 .dll,客户端编译时需要头文件和 .a,运行时需要 .dll;
  3. 静态链接库 则是另外一种新的机制,构建最终只生成 .a 文件,客户端调用时需要 .a 文件,运行时则不需要任何库文件,类似于客户端在编译时将库包进了自己的exe中;
  4. Qt插件不再多说,参考Qt插件系统文章,就是一种动态加载DLL的方法,但是又把加载的细节隐藏了;

综上所属,MingW 下的链接库相比于 MSVC,着实简单了很多,把内部的很多复杂的细节隐藏在Qt的内部系统中,对使用者来说,更加方便。

链接库的使用

下面就来简单介绍一下这些库的使用,Qt的插件不在讨论之列,请参考Qt插件系统文章。介绍中会忽略一些不重要的细节,我们认为你应该对C++和Qt有一个较深的认识,若没有,请自行去学习相关知识。同时,我们顺带简单介绍一些 .pro 文件的配置。

共享库

(1)创建共享库

共享库类似静态链接,生成.a文件和.dll文件。

按照正常流程新建库项目,类型选择 动态库,最终生成的项目列表中如下如所示:

可以看出,除了需要导出的类外,额外还有一个XXX_global.h的文件,文件代码如下:

#ifndef FIRECONTROL_GLOBAL_H
#define FIRECONTROL_GLOBAL_H #include <QtCore/qglobal.h> #if defined(FIRECONTROL_LIBRARY)
# define FIRECONTROLSHARED_EXPORT Q_DECL_EXPORT
#else
# define FIRECONTROLSHARED_EXPORT Q_DECL_IMPORT
#endif #endif // FIRECONTROL_GLOBAL_H

了解 MSVC 的dll导出的都能了解,这里其实是对 __declspec(dllexport)__declspec(dllimport) 进行一种巧妙的声明,因为导出需要使用export,导入需要使用import,为了避免在库和客户端中重复地进行export和import的声明,这里使用宏定义进行统一声明,详细说明可以参考DLL的导出和调用的文章。

在需要导出的类和方法前面使用 FIRECONTROLSHARED_EXPORT 声明即可,客户端调用时也需要将这个文件include进来。

当然,如果你对导出DLL的一个比较清晰的认识,也可以删除这个文件,自己定义。

(2)pro文件

QT       -= gui

TARGET = FireControl
TEMPLATE = lib #表示这是一个库项目 DEFINES += FIRECONTROL_LIBRARY SOURCES += FireControlManager.cpp HEADERS += FireControlManager.h\
firecontrol_global.h unix {
target.path = /usr/lib
INSTALLS += target
}
#上面为创建时自动生成,以下为新增
DESTDIR = $$PWD/../SystemWindow/lib #最终编译文件的生成路径,包括.a和.dll
DLLDESTDIR = $$PWD/../../../Service #dll文件的生成路径

(3)调用共享库

在调用端右击->添加库,选择生成 .a 文件,即可自动在 pro文件中添加加载设置。当然,也可以不适用GUI操作,直接修改pro文件以达到添加库的目的。

我们希望调用端和库项目分开构建,所以这里选择外部库

添加.a的库文件和头文件的包含目录,并配置一些链接方法

调用设置完成后,pro文件如下:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = SystemWindow
TEMPLATE = app SOURCES += main.cpp\
MainBench.cpp HEADERS += MainBench.h FORMS += MainBench.ui #以下即为自动生成的加载库设置
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/ -lFireControl
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/ -lFireControl
else:unix:!macx: LIBS += -L$$PWD/lib/ -lFireControl INCLUDEPATH += $$PWD/../FireControl
DEPENDPATH += $$PWD/../FireControl
DESTDIR = $$PWD/../../../Service #目标生成路径

最后,可以在客户端使用库导出的类了,当然不要忘了添加头文件。

静态库

(1)创建静态库

静态最终只会生成 .a 文件。

创建库项目时,选择静态库,完成之后,项目目录的内容和目录中,除了没有入口的main函数外,其他都和普通项目没有什么区别,而真正的区别在于pro文件的配置中。

(2)pro文件

QT       -= gui

TARGET = untitled
TEMPLATE = lib #表示这是一个库项目
CONFIG += staticlib #表示这是一个静态库 SOURCES += untitled.cpp HEADERS += untitled.h
unix {
target.path = /usr/lib
INSTALLS += target
}
DESTDIR = $$PWD/../SystemWindow/lib #生成路径

(3)调用静态库

调用方法和调用共享库类似,这里不做赘述,最终实际运行时不需要dll文件

总结

共享库和静态库各有各的优势,从最简单的层面上来看:

使用静态库可以将大项目区分开,即分模块显示项目,便于维护;

使用共项目也是如此,而且可以在不修改客户端的情况下,修改库内容的实现,只要接口不变,最终替换dll即可完成内容的改变。

但是看起来静态库有些鸡肋,具体还有哪些好处,留待日后发现。

QtCreator中使用链接库的更多相关文章

  1. linux c静态链接库与动态链接库

    库函数是我们编程的时候经常用到的,我们协作编程的时候可以将常用的函数封装成库供大家使用,这样能够提高大家的工作效率.对于库函数,它分为动态链接库和静态链接库.对于静态链接库我们必须是连接到可执行文件中 ...

  2. linux下C/C++编译时系统搜索 include 和 链接库 文件路径的指定

     C/C++程序在linux下被编译和连接时,GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径.自己指定的路径就不说了,这里说明一下系统自动搜索的路径.   ...

  3. Linux中安装C++编译器codeBlock,并配置opencv链接库

    1.Linux中安装codeBlock https://blog.csdn.net/xinyunyishui/article/details/50967395 2.CodeBlock中的中文显示不完全 ...

  4. Linux中的共享链接库shared libraries

    可执行文件的静态链接和动态链接静态链接会将需要的库函数在编译时一并包含, 所以体积会比较大. 使用ldd命令查看可执行文件链接的库 $ ldd /sbin/ldconfig not a dynamic ...

  5. VS2010中如何将动态链接库改成静态链接库

    VS2010中如何将动态链接库改成静态链接库 VS2010静态编译生成的.exe可执行文件,可以免安装免DLL在其他电脑直接运行. 静态编译:就是在编译可执行文件的时候,将可执行文件需要调用的对应动态 ...

  6. Linux编程中链接库的使用

    链接库本质上是一段可执行的二进制代码,可以被操作系统载入内存执行.按加载的时机不同,链接库可以分为静态链接库和动态链接库. 静态链接库:编译过程中加载进可执行文件的库(静态库省去了运行时加载的消耗,但 ...

  7. 介绍静态链接库和动态链接库的差别,及在VC++6.0中的建立和使用

    首先介绍一下链接库:链接库分为动态链接库和静态链接库两种 LIB是静态链接库,在程序编译连接的时候是静态链接,其相应的文件格式是.lib. 即当程序採用静态链接库的时候..lib文件里的函数被链接到终 ...

  8. C运行时库(C Run-time Library)详解(提供的另一个最重要的功能是为应用程序添加启动函数。Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)

    一.什么是C运行时库 1)C运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 2)C 语言是所谓的“ ...

  9. VC++中的C运行时库浅析(控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)

    1.概论 运行时库是程序在运行时所需要的库文件,通常运行时库是以LIB或DLL形式提供的.C运行时库诞生于20世纪70年代,当时的程序世界还很单纯,应用程序都是单线程的,多任务或多线程机制在此时还属于 ...

随机推荐

  1. 【Java】 语言基础习题汇总 [2] 面向对象

    30 面向对象的三条主线和面向对象的编程思想? 类与类的成员 : 属性.方法.构造器.代码块.内部类. 面向对象的三大特征:封装.继承.多态[如果还有一个,那就是抽象] 关键字:this.super. ...

  2. ThreeJs 导入外部三维模型,并实现鼠标滚动放大缩小旋转效果

    let i = ; function init() { // create a scene, that will hold all our elements such as objects, came ...

  3. SpringBoot连接Redis服务出现DENIED Redis is running in protected mode because protected mode is enabled

    修改redis.conf,yes 改为 no

  4. stand up meeting 11/16/2015

    第一周,熟悉任务中~ 大致写下一天的工作: 冯晓云:熟悉bing接口,本意是调在线的必应词典API,参阅了大量C#调用API开发.net的工作,[约莫是因为有个窗口互动性更强,所以这样的工作更有趣,也 ...

  5. K - Downgrade Gym - 101775K

    题目大意:一天不玩相当于A-B中将A转换为经验值,B舍弃掉,然后A=1,在通过升级所需要的经验值来判断可以升几级 题目连接:https://codeforces.com/gym/101775/prob ...

  6. 2.hover的使用

    1. 自身的hover div :hover{  :hover前要有空格  } 2.hover指向子元素 father:hover .childer {   :hover前不能有空格   } 3.ho ...

  7. [转载]绕过CDN查找真实IP方法总结

    前言 类似备忘录形式记录一下,这里结合了几篇绕过CDN寻找真实IP的文章,总结一下绕过CDN查找真实的IP的方法 介绍 CDN的全称是Content Delivery Network,即内容分发网络. ...

  8. 《并发编程的艺术》阅读笔记之Sychronized

    概述 在JDK1.6中,锁一共四种状态,级别由低到高依次是:无锁状态.偏向锁状态.轻量级锁状态和重量级锁状态.锁可以升级但不能降级,这是为了提高获得锁和释放锁的效率.只有重量级锁涉及到操作系统线程切换 ...

  9. HTML+CSS教程(一)简介及其基本标签的使用方法

    一.前端 HTML(结构):HyPer TEXT Markup LanguageCSS(样式): 样式就是对于结构的一种美化JavaScript(js: 行为/ 提供了用户和界面的交互方式)jQuer ...

  10. Websec level 30

    前言 昨天在易霖博搞的网络安全与执法竞赛看到的一道web题,实际上就是用两个原题凑起来的.. 不过后面的一关没见过这里简单记录一下 第一关 打开是个登录界面,和BJDCTF的简单注入一模一样,连密码都 ...