简述
摘自*:
静态链接库(Statically-linked library),或称静态库,是一个外部函数与变量的集合体。静态库的文件内容,通常包含一堆程序员自定的变量与函数,其内容不像动态链接库那么复杂,在编译期间由编译器与连接器将它集成至应用程序内,并制作成目标文件以及可以独立运作的可执行文件。而这个可执行文件与编译可执行文件的程序,都是一种程序的静态创建(static build)。以过去的观点来说,库只能算是静态(static)类型。
版权所有:一去丶二三里,转载请注明出处:http://blog.csdn.net/liang19890820
创建静态链接库
创建静态链接库的步骤和共享库基本相同,唯一的区别是【类型】需要选择“静态链接库”:
这里,将项目名称命名为 StaticLib
。
项目文件
在项目创建完成之后,Qt Creator 会自动生成相关的文件,目录结构如下:
与共享库不同,这里并没有出现了一个名为 {projectName}_global.h
的文件,Why?这是因为静态链接库将被内置到应用程序中,所以无需在 .h
文件中设置导出和导入符号的特殊功能。
查看 .pro
,并对其稍作修改:
TARGET = StaticLib
# 新增部分
CONFIG += debug_and_release
CONFIG(debug, debug|release) {
unix: TARGET = $$join(TARGET,,,_debug)
else: TARGET = $$join(TARGET,,,d)
}
TEMPLATE = lib
CONFIG += staticlib
与共享库的另一个不同之处在于:这里多了一个 CONFIG
选项,其值为 staticlib
。没错,这正是要告诉 qmake,我们需要生成的是一个静态链接库。
生成静态链接库
可以看到,生成的库中只有一个简单的类定义,对其稍作修改。
staticlib.h
内容如下:
#ifndef STATICLIB_H
#define STATICLIB_H
int subtract(int x, int y);
class StaticLib
{
public:
StaticLib();
int add(int x, int y);
};
#endif // STATICLIB_H
staticlib.cpp
内容如下:
#include "staticlib.h"
int subtract(int x, int y)
{
return x - y;
}
StaticLib::StaticLib()
{
}
int StaticLib::add(int x, int y)
{
return x + y;
}
构建(不运行)项目,会生成相应的 .lib
文件。
注意: Debug
版本为 StaticLibd.lib
(带 d),Release
版本为 StaticLib.lib
(不带 d)。
使用静态链接库
创建一个简单的客户端 - Qt Console Application,并使用静态链接库,效果如下:
项目创建成功后,将刚才生成的静态链接库组织成以下结构:
- StaticLibClient/
- StaticLibClient.pro
- main.cpp
- 3rdparty/
- StaticLib/
- include/
- staticlib.h
- lib/
- StaticLibd.lib
- StaticLib.lib
静态链接库的使用方式和共享库类似,不同的是这里将【链接】选择为“静态”:
这时,.pro
中会自动添加以下代码:
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/3rdparty/StaticLib/lib/ -lStaticLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/3rdparty/StaticLib/lib/ -lStaticLibd
INCLUDEPATH += $$PWD/3rdparty/StaticLib/include
DEPENDPATH += $$PWD/3rdparty/StaticLib/include
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/3rdparty/StaticLib/lib/libStaticLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/3rdparty/StaticLib/lib/libStaticLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/3rdparty/StaticLib/lib/StaticLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/3rdparty/StaticLib/lib/StaticLibd.lib
类似于为共享库加载所做的工作,需要将 INCLUDEPATH
指向头文件所在目录,并将 LIBS
变量指向 .lib
文件。但是,这里多了一个变量 - PRE_TARGETDEPS
,它用于列出目标所依赖的库,尤其是对于显式列出相关的静态库很有用。
建议: 如果使用静态链接库,应该始终同时使用 LIBS
和 PRE_TARGETDEPS
。
开始测试,main.cpp
内容如下:
#include <QCoreApplication>
#include <qDebug>
#include "staticlib.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 测试库
StaticLib lib;
qDebug() << lib.add(2, 3);
qDebug() << subtract(5, 2);
return a.exec();
}
OK,运行程序,效果如上所示。
选择哪种方式
目前为止,介绍了两种库 - 共享库和静态链接库,但是分享了三种使用方式。
到底如何选择?这完全取决于你的需要。
- 在创建共享库时,需要将其部署到应用程序中。从好的方面来说,与共享库相关联的应用程序和库很小。
- 是否要使用
QLibrary
在运行时加载.dll
,取决于是否访问了.h
头文件和.lib
文件。如果无法访问这些文件,那么QLibrary
是另一种选择。 - 静态链接会生成一个独立的可执行文件,这样做的好处是只需要部署几个文件,缺点是可执行文件很大。