动态库和静态库(代码片段)

小倪同学-_- 小倪同学-_-     2022-12-01     120

关键词:

文章目录

动静态库的基本原理

我们知道从源文件到可执行程序需要如下经历4个步骤

  1. 预处理: 完成头文件展开、去注释、宏替换、条件编译等,形成xxx.i文件。
  2. 编译: 完成词法分析、语法分析、语义分析、符号汇总等,检查无误后将代码翻译成汇编指令,形成xxx.s文件。
  3. 汇编: 将汇编指令转换成二进制指令,形成xxx.o文件。
  4. 链接: 将生成的各个xxx.o文件进行链接,形成可执行程序。

这里的动静态库本质上就是xxx.o文件的集合

初识动静态库

下面用一份简单的代码来认识动静态库

#include <stdio.h>

int main()

	printf("hello world\\n");
	return 0;

可以通过 ldd+文件名 来查看一个可执行程序所依赖的库文件。

使用 file+文件名 可以查看文件类型

图中 libc.so.6 表示c语言动态库,在Linux中生成的可执行程序默认情况下是动态库链接。

想要让生成的可执行程序为动态链接,需要添加 -static 选项。


从图中我们发现静态生成的可执行程序比动态生成的可执行程序要大得多

查看文件类型

静态链接生成的可执行程序并不依赖其他库文件,此时当我们使用ldd 文件名命令查看该可执行程序所依赖的库文件时就会看到以下信息。

动静态库各自特点

静态库:

静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。

优点:

  • 不依赖库,库文件丢失对其没有影响

缺点:

  • 体积大,浪费资源(磁盘,内存)

动态库:

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

优点:

  • 体积小,节省资源

缺点:

  • 依赖库,一旦库文件丢失,程序便无法运行

静态库的打包和使用

下面演示静态库的打包和使用,先创建两个源文件add.c,sub.c,再创建两个头文件add.h,sub.h。

add.h

#pragma once

extern int my_add(int x, int y);

add.c

#include "add.h"

int my_add(int x, int y)

	return x + y;

sub.h

#pragma once

extern int my_sub(int x, int y);

sub.c

#include "sub.h"

int my_sub(int x, int y)

	return x - y;

打包

  1. 让所有源文件生成对应的目标文件

  1. 使用ar命令将所有目标文件打包为静态库


ar命令是gnu的归档工具,常用于将目标文件打包为静态库,下面我们使用ar命令的-r选项和-c选项进行打包。

  • -r(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。
  • -c(create):建立静态库文件。
  1. 将头文件和生成的静态库组合

这里可以将头文件sub.h和add.h,静态库文件libmymath.a放入新建的目录lib下,此时可以将lib给别人使用了。

使用

下面尝试使用我们打包好的静态库文件lib

创建main.c文件

#include<stdio.h>
#include "add.h"
#include "sub.h"

int main()

      printf("%d\\n",my_add(10,20));
      printf("%d\\n",my_sub(10,20));

      return 0;

现在该目录下就只有main.c和我们刚才打包好的静态库。

此时使用gcc编译main.c生成可执行程序时需要携带三个选项:

  • -I:指定头文件搜索路径。
  • -L:指定库文件搜索路径。
  • -l:指明需要链接库文件路径下的哪一个库。

注意:

  1. 因为编译器不知道你所包含的头文件add.h在哪里,所以需要指定头文件的搜索路径。
  2. 因为头文件add.h当中只有my_add函数的声明,并没有该函数的定义,所以还需要指定所要链接库文件的搜索路径。
  3. 实际中,在库文件的lib目录下可能会有大量的库文件,因此我们需要指明需要链接库文件路径下的哪一个库。库文件名去掉前缀lib,再去掉后缀.so或者.a及其后面的版本号,剩下的就是这个库的名字。
  4. 我们也可以将头文件和库文件拷贝到系统路径下。

了解静态库的使用规则后,我们不禁会产生疑问,为什么之前使用gcc编译的时候没有指明过库名字?

因为我们使用gcc编译的是C语言,而gcc就是用来编译C程序的,所以gcc编译的时候默认就找的是C库,但此时我们要链接的是哪一个库编译器是不知道的,因此我们还是需要使用-l选项,指明需要链接库文件路径下的哪一个库。

实际上我们拷贝头文件和库文件到系统路径下的过程,就是安装库的过程。

动态库的打包与使用

我们还是用上面四个文件演示

这里我们使用Makefile文件

这里的makefile文件可以将要生成的文件一次性全部生成,如下图

注意:

  • shared: 表示生成共享库格式
  • fPIC:产生位置无关码

再将生成的头文件和动态库(libmymath.so)打包

使用

还是用刚才的main.c文件演示

用和静态库一样的方法生成可执行程序


运行一下,发现生成的可执行程序报错了

用ldd指令看看可执行程序所属

从图中可以看到,此时可执行程序所依赖的动态库是没有被找到的。

解决方法:

  1. 更改LD_LIBRARY_PATH

LD_LIBRARY_PATH是程序运行动态查找库时所要搜索的路径,我们只需将动态库所在的目录路径添加到LD_LIBRARY_PATH环境变量当中即可。

此时系统可以找到该可执行程序所依赖的动态库,程序也可以执行了。

  1. 配置/etc/ld.so.conf.d/

/etc/ld.so.conf.d/路径下存放的全部都是以.conf为后缀的配置文件,而这些配置文件当中存放的都是路径,系统会自动在/etc/ld.so.conf.d/路径下找所有配置文件里面的路径,之后就会在每个路径下查找你所需要的库。我们若是将自己库文件的路径也放到该路径下,那么当可执行程序运行时,系统就能够找到我们的库文件了。

在/etc/ld.so.conf.d/路径下新建一个以.conf为后缀的配置文件,将动态库的路径拷贝到该文件下

此时我们用ldd命令查看可执行程序时,发现系统还是没有找到该可执行程序所依赖的动态库。

我们需要使用ldconfig命令将配置文件更新一下

此时可以正常运行文件了

  1. 拷贝.so文件到系统共享库路径下

方法二和方法三不推荐,会污染路径。

静态链接库和动态链接库(代码片段)

静态链接库和动态链接库共有两种库:一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamiclinklibrary。一种是LIB包含函数代码本身,在编译时直接... 查看详情

静态库和共享库(代码片段)

...接阶段被复制到了程序中,和程序运行的时候没有关系。动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存... 查看详情

gcc编译使用动态链接库和静态链接库(代码片段)

1库的分类根据链接时期的不同,库又有静态库和动态库之分。静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。有别于静态... 查看详情

动态库和静态库(代码片段)

...动静态库动静态库各自特点静态库的打包和使用打包使用动态库的打包与使用使用动静态库的基本原理我们知道从源文件到可执行程序需要如下经历4个步骤预处理:完成头文件展开、去注释、宏替换、条件编译等,形成x... 查看详情

《c语言杂记》静态库和动态库(linux版)(代码片段)

1静态库和动态库概述库是一种软件组件技术,库里面封装了数据和函数。库的使用可以使程序模块化。库有两种:静态库和动态库。Windows系统包括静态链接库(.lib文件)和动态链接库(.dll文件)。Linux通... 查看详情

《c语言杂记》静态库和动态库(linux版)(代码片段)

1静态库和动态库概述库是一种软件组件技术,库里面封装了数据和函数。库的使用可以使程序模块化。库有两种:静态库和动态库。Windows系统包括静态链接库(.lib文件)和动态链接库(.dll文件)。Linux通... 查看详情

动态库和静态库(代码片段)

前提:本文是基于Linux系统下的编程与学习补充:头文件卫士,避免头文件重复包含。//头文件卫士#ifndef__HEAD_H__#define__HEAD_H__//头文件内容#endif//__HEAD_H__命令:nmnm 二进制文件名;   可以查看二进制文件的符号表那... 查看详情

linux动态库和静态库(代码片段)

...静态库动静态库各自的特征静态库的打包与使用打包使用动态库的打包与使用打包使用动静态库的基本原理动静态库的本质是可执行程序的“半成品”。我们都知道,一堆源文件和头文件最终变成一个可执行程序需要经历以... 查看详情

linux静态库和共享(动态)库的创建与使用详解(代码片段)

文章目录Linux静态库和共享(动态)库库的介绍使用库有什么好处库制作完成后,如何给用户使用静态库(staticlibrary)静态库的制作ar工具创建lib过程静态库的使用源代码静态库的优缺点优点:缺点:共享库... 查看详情

linux下c/c++编程开发静态库和动态库(代码片段)

...、静态库2.1命名规则2.2静态库的制作2.3静态库的使用三、动态库3.1命名规则3.2动态库的制作3.3动态库的使用3.3.1修改环境变量3.3.2修改/etc/ld.so.cache文件列表3.3.3/lib或/usr/lib目录四、动静态库的优缺点4.1静态库4.2动态库前言下面的... 查看详情

linux下c/c++编程开发静态库和动态库(代码片段)

...、静态库2.1命名规则2.2静态库的制作2.3静态库的使用三、动态库3.1命名规则3.2动态库的制作3.3动态库的使用3.3.1修改环境变量3.3.2修改/etc/ld.so.cache文件列表3.3.3/lib或/usr/lib目录四、动静态库的优缺点4.1静态库4.2动态库前言下面的... 查看详情

ios静态库和framework区别(代码片段)

...么是库库是共享程序代码的方式,一般分为静态库和动态库。静态库与动态库的区别静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。动态库:链接时不复制,程序运行时由系统动... 查看详情

详解linux下静态库/动态库的生成和使用(含代码示例和操作流程)&&动态库和静态库的区别(代码片段)

文章目录一、库的概念Windows的库Linux的库二、动态库和静态库的区别1.载入顺序不同2.大小与共享的差异3.库函数调用的差异三、静态库的创建和使用1.创建静态库的步骤:(一)ar命令的使用方法(二)生成静... 查看详情

c++学习(四九零)add_library生成动态库和静态库(代码片段)

1、静态库add_library(hello_librarySTATICsrc/hello.cpp)2、动态库注意这里是SHARED,而不是DYNAMICadd_library(hello_librarySHAREDsrc/hello.cpp) 查看详情

c++学习(四九零)add_library生成动态库和静态库(代码片段)

1、静态库add_library(hello_librarySTATICsrc/hello.cpp)2、动态库注意这里是SHARED,而不是DYNAMICadd_library(hello_librarySHAREDsrc/hello.cpp) 查看详情

linux环境下的静态链接库和动态链接库(代码片段)

什么是链接库计算机中,有些文件专门用于存储可以重复使用的代码块,例如功能实用的函数或者类,我们通常将它们称为库文件,简称“库”(Library)。以C语言为例,如下为大家展示的就是一个函数库://myMath.cintadd(inta,intb)r... 查看详情

《c语言杂记》静态库和动态库(windows版)(代码片段)

4Windows创建和使用静态库笔者这里使用的是VS2015,当然也可以使用其他工具。4.1生成静态库1.首先打开VS,先新建一个项目,选择win32控制台应用程序,当然选择win32项目也可以。2.接下来选择“下一步”进入应用程... 查看详情

《c语言杂记》静态库和动态库(windows版)(代码片段)

4Windows创建和使用静态库笔者这里使用的是VS2015,当然也可以使用其他工具。4.1生成静态库1.首先打开VS,先新建一个项目,选择win32控制台应用程序,当然选择win32项目也可以。2.接下来选择“下一步”进入应用程... 查看详情