参考:(19条消息) 静态链接库与动态链接库详解_天糊土的博客-优快云博客
(19条消息) 静态链接库和动态链接库_动态链接库和静态链接库_大胡子的艾娃的博客-优快云博客
一、库文件
库是一组预先编译好的方法的集合,是计算机上的一类文件,提供给使用者一些开箱即用的变量、函数或类。
库文件的调用方法:以 C 语言中的 printf() 输出函数为例,程序中只需引入 <stdio.h> 头文件,即可调用 printf() 函数。
与头文件的区别:头文件只存储变量、函数或者类等这些功能模块的声明部分,库文件才负责存储各模块具体的实现部分。即所有的库文件都提供有相应的头文件作为调用它的接口,库文件是无法直接使用的,只能通过头文件间接调用。头文件和库文件相结合的访问机制,最大的好处在于,有时候我们只想让别人使用自己实现的功能,并不想公开实现功能的源码,就可以将其制作为库文件,这样用户获取到的是二进制文件,而头文件又只包含声明部分,这样就实现了“将源码隐藏起来”的目的,且不会影响用户使用。
二、静态库和动态库简介
库文件分为静态库和动态库,静态库和动态库的区别体现在程序的链接阶段。
C或C++程序从源文件到生成可执行文件需经历 4 个阶段,分别为预处理、编译、汇编和链接。链接阶段所要完成的工作,是将同一项目中各源文件生成的目标文件和程序中用到的库文件整合为一个可执行文件。虽然库文件明确用于链接,但编译器提供了2种实现链接的方式,分别称为静态链接和动态链接。采用静态链接方式实现链接操作的库文件称为静态链接库;采用动态链接方式实现链接操作的库文件称为动态链接库。
一般来说,Windows的静态库文件扩展名是 .lib,动态库文件扩展名是 .dll (Dynamic-Link Libraries);Linux的静态库扩展名是 .a,动态库扩展名是 .so (Shared Object)。内容一样,都是将函数封装,编译后生成.o文件,将所有 .o 文件合并生成库文件,再将供自己或他人调用。好处在于编译后的库文件的源代码被加密,使用者看不到,可保密。
2.1 静态链接库
把调要调用的函数或者过程直接链接到可执行文件(dll或exe)中,成为可执行文件的一部分。该文件中包含了运行所需的全部代码。
优点:
链接该静态库可执行文件(dll或exe等)的使用,无需再需要该静态库。
缺点:
a)当多个程序都要调用相同函数时,内存中就会存在这个函数的多个复制,存在资源浪费。
b)当静态库发生修改时,不仅该静态库要从新编译,引用该静态库的模块都需要从新编译。
2.2 动态链接库
动态链接调用的函数代码并没有被复制到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在操作系统的管理下,才在应用程序与相应的动态链接库(dynamic link library,dll)之间建立链接关系。当要执行调用.dll文件中的函数时,根据链接产生的重定位信息,操作系统才转去执行.dll文件中相应的函数代码。
优点:
当修改动态库的代码,但重定位信息没有变化,引用该动态库的模块无需从新编译。
缺点:
可移植性差,无法独立运行,必须借助相应的库文件。
三、静态链接库的创建与使用
3.1 静态链接库的创建
- 将源文件加工为静态链接库
静态链接库不能随意起名,需遵循“libxxx.a”这样的命名规则
- 直接创建静态链接库
3.2静态链接库的使用
在程序的链接阶段,将静态链接库和目标文件一起执行链接操作,从而生成可执行文件。
以 demo 项目为例,首先我们将 main.c 文件编译为目标文件:
[root@bogon demo]# gcc -c main.c
[root@bogon demo]# ls
add.c div.c libmymath.a main.o sub.c
test.h add.o div.o main.c sub.o
在此基础上,我们可以直接执行如下命令,即可完成链接操作,默认生成可执行文件a.out(或者利用-o选项生成其他命名文件)。-static 选项表示强制 GCC 编译器使用静态链接库。
[root@bogon demo]# gcc -static main.o libmymath.a
[root@bogon demo]# ls
add.c a.out div.o main.c sub.c test.h
add.o div.c libmymath.a main.o sub.o
注意,上面这种写法只会在当前目录查找libmymath.a静态链接库,如果 GCC 编译器提示无法找到 libmymath.a,还可以使用如下方式完成链接操作。其中 -L 选项用于向 GCC 编译器指明静态链接库的存储位置; -l(小写的 L)选项用于指明所需静态链接库的名称。这里的名称指的是 xxx 部分,建议将 -l 和 xxx 直接连用(即 -lxxx),中间不需有空格;-L与路径之间可以有空格,也可以没有空格。
[root@bogon demo]# gcc main.o -static -L/root/demo/ -lmymath
[root@bogon demo]# ls
add.c a.out div.o main.c sub.c test.h
add.o div.c libmymath.a main.o sub.o
四、动态链接库的创建与使用
ydServer是非开源的,不对外公布其源码,类和函数的声明都放在include文件夹下的.h头文件中,这些类和函数的实现源代码不公开,但其动态链接库放在linux64、win32、win64这三个文件夹中,分别对应linux、32位windows和64位windows操作系统。