广告
返回顶部
首页 > 资讯 > 操作系统 >如何在 Linux 中使用动态和静态库
  • 871
分享到

如何在 Linux 中使用动态和静态库

2023-06-15 12:06:32 871人浏览 泡泡鱼
摘要

本篇内容介绍了“如何在 linux 中使用动态和静态库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!了解 Linux 如何使用库,包括静态库

本篇内容介绍了“如何在 linux 中使用动态和静态库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

了解 Linux 如何使用库,包括静态库和动态库的差别,有助于你解决依赖问题。

Linux 从某种意义上来说就是一堆相互依赖的静态和动态库。对于 Linux 系统新手来说,库的整个处理过程简直是个迷。但对有经验的人来说,被构建进操作系统的大量共享代码对于编写新应用来说却是个优点。

为了让你熟悉这个话题,我准备了一个小巧的 应用例子 来展示在普通的 Linux 发行版(在其他操作系统上未验证)上是经常是如何处理库的。为了用这个例子来跟上这个需要动手的教程,请打开命令行输入:

git clone https://GitHub.com/hANSIc99/library_sample$ cd library_sample/$ makecc -c main.c -Wall -Werrorcc -c libmy_static_a.c -o libmy_static_a.o -Wall -Werrorcc -c libmy_static_b.c -o libmy_static_b.o -Wall -Werrorar -rsv libmy_static.a libmy_static_a.o libmy_static_b.oar: creating libmy_static.aa - libmy_static_a.oa - libmy_static_b.occ -c -fPIC libmy_shared.c -o libmy_shared.occ -shared -o libmy_shared.so libmy_shared.o$ make cleanrm *.o

当执行完这些命令,这些文件应当被添加进目录下(执行 ls 来查看):

my_applibmy_static.alibmy_shared.so

关于静态链接

当你的应用链接了一个静态库,这个库的代码就变成了可执行文件的一部分。这个动作只在链接过程中执行一次,这些静态库通常以 .a 扩展符结尾。

静态库是多个目标object文件的归档arcHive(ar)。这些目标文件通常是 ELF 格式的。ELF 是 可执行可链接格式Executable and Linkable FORMat 的简写,它与多个操作系统兼容。

file 命令的输出可以告诉你静态库 libmy_static.a 是 ar 格式的归档文件类型。

$ file libmy_static.alibmy_static.a: current ar archive

使用 ar -t,你可以看到归档文件的内部。它展示了两个目标文件:

$ ar -t libmy_static.alibmy_static_a.olibmy_static_b.o

你可以用 ax -x <archive-file> 命令来提取归档文件的文件。被提出的都是 ELF 格式的目标文件:

$ ar -x libmy_static.a$ file libmy_static_a.olibmy_static_a.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

关于动态链接

动态链接指的是使用共享库。共享库通常以 .so 的扩展名结尾(“共享对象shared object” 的简写)。

共享库是 Linux 系统中依赖管理的最常用方法。这些共享库在应用启动前被载入内存,当多个应用都需要同一个库时,这个库在系统中只会被加载一次。这个特性减少了应用的内存占用。

另外一个值得注意的地方是,当一个共享库的 bug 被修复后,所有引用了这个库的应用都会受益。但这也意味着,如果一个 bug 还没被发现,那所有相关的应用都会遭受这个 bug 影响(如果这个应用使用了受影响的部分)。

当一个应用需要某个特定版本的库,但是链接器linker只知道某个不兼容版本的位置,对于初学者来说这个问题非常棘手。在这个场景下,你必须帮助链接器找到正确版本的路径。

尽管这不是一个每天都会遇到的问题,但是理解动态链接的原理总是有助于你修复类似的问题。

幸运的是,动态链接的机制其实非常简洁明了。

为了检查一个应用在启动时需要哪些库,你可以使用 ldd 命令,它会打印出给定文件所需的动态库:

$ ldd my_app        linux-vdso.so.1 (0x00007ffd1299c000)        libmy_shared.so => not found        libc.so.6 => /lib64/libc.so.6 (0x00007f56b869b000)        /lib64/ld-linux-x86-64.so.2 (0x00007f56b8881000)

可以注意到 libmy_shared.so 库是代码仓库的一部分,但是没有被找到。这是因为负责在应用启动之前将所有依赖加载进内存的动态链接器没有在它搜索的标准路径下找到这个库。

对新手来说,与常用库(例如 bizp2)版本不兼容相关的问题往往十分令人困惑。一种方法是把该仓库的路径加入到环境变量 LD_LIBRARY_PATH 中来告诉链接器去哪里找到正确的版本。在本例中,正确的版本就在这个目录下,所以你可以导出它至环境变量:

$ LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH$ export LD_LIBRARY_PATH

现在动态链接器知道去哪找库了,应用也可以执行了。你可以再次执行 ldd 去调用动态链接器,它会检查应用的依赖然后加载进内存。内存地址会在对象路径后展示:

$ ldd my_app        linux-vdso.so.1 (0x00007ffd385f7000)        libmy_shared.so => /home/stephan/library_sample/libmy_shared.so (0x00007f3fad401000)        libc.so.6 => /lib64/libc.so.6 (0x00007f3fad21d000)        /lib64/ld-linux-x86-64.so.2 (0x00007f3fad408000)

想知道哪个链接器被调用了,你可以用 file 命令:

$ file my_appmy_app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=26c677b771122b4c99f0fd9ee001e6c743550fa6, for GNU/Linux 3.2.0, not stripped

链接器 /lib64/ld-linux-x86&ndash;64.so.2 是一个指向 ld-2.30.so 的软链接,它也是我的 Linux 发行版的默认链接器:

$ file /lib64/ld-linux-x86-64.so.2/lib64/ld-linux-x86-64.so.2: symbolic link to ld-2.31.so

回头看看 ldd 命令的输出,你还可以看到(在 libmy_shared.so 边上)每个依赖都以一个数字结尾(例如 /lib64/libc.so.6)。共享对象的常见命名格式为:

libXYZ.so.<MAJOR>.<MINOR>

在我的系统中,libc.so.6 也是指向同一目录下的共享对象 libc-2.31.so 的软链接。

$ file /lib64/libc.so.6/lib64/libc.so.6: symbolic link to libc-2.31.so

如果你正在面对一个应用因为加载库的版本不对导致无法启动的问题,有很大可能你可以通过检查整理这些软链接或者确定正确的搜索路径(查看下方“动态加载器:ld.so”一节)来解决这个问题。

更为详细的信息请查看 ldd 手册页。

动态加载

动态加载的意思是一个库(例如一个 .so 文件)在程序的运行时被加载。这是使用某种特定的编程方法实现的。

当一个应用使用可以在运行时改变的插件时,就会使用动态加载。

查看 dlopen 手册页 获取更多信息。

动态加载器:ld.so

在 Linux 系统中,你几乎总是正在跟共享库打交道,所以必须有个机制来检测一个应用的依赖并将其加载进内存中。

ld.so 按以下顺序在这些地方寻找共享对象:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 应用的绝对路径或相对路径下(用 GCC 编译器的 -rpath 选项硬编码的)

  3. 环境变量 LD_LIBRARY_PATH

  4. /etc/ld.so.cache 文件

需要记住的是,将一个库加到系统库归档 /usr/lib64 中需要管理员权限。你可以手动拷贝 libmy_shared.so 至库归档中来让应用可以运行,而避免设置 LD_LIBRARY_PATH

unset LD_LIBRARY_PATHsudo cp libmy_shared.so /usr/lib64/

当你运行 ldd 时,你现在可以看到归档库的路径被展示出来:

$ ldd my_app        linux-vdso.so.1 (0x00007ffe82fab000)        libmy_shared.so => /lib64/libmy_shared.so (0x00007f0a963e0000)        libc.so.6 => /lib64/libc.so.6 (0x00007f0a96216000)        /lib64/ld-linux-x86-64.so.2 (0x00007f0a96401000)

在编译时定制共享库

如果你想你的应用使用你的共享库,你可以在编译时指定一个绝对或相对路径。

编辑 makefile(第 10 行)然后通过 make -B 来重新编译程序。然后 ldd 输出显示 libmy_shared.so 和它的绝对路径一起被列出来了。

把这个:

CFLAGS =-Wall -Werror -Wl,-rpath,$(shell pwd)

改成这个(记得修改用户名):

CFLAGS =/home/stephan/library_sample/libmy_shared.so

然后重新编译:

$ make

确认下它正在使用你设定的绝对路径,你可以在输出的第二行看到:

$ ldd my_app    linux-vdso.so.1 (0x00007ffe143ed000)        libmy_shared.so => /lib64/libmy_shared.so (0x00007fe50926d000)        /home/stephan/library_sample/libmy_shared.so (0x00007fe509268000)        libc.so.6 => /lib64/libc.so.6 (0x00007fe50909e000)        /lib64/ld-linux-x86-64.so.2 (0x00007fe50928e000)

这是个不错的例子,但是如果你在编写给其他人用的库,它是怎样工作的呢?新库的路径可以通过写入 /etc/ld.so.conf 或是在 /etc/ld.so.conf.d/ 目录下创建一个包含路径的 <library-name>.conf 文件来注册至系统。之后,你必须执行 ldconfig 命令来覆写 ld.so.cache 文件。这一步有时候在你装了携带特殊的共享库的程序来说是不可省略的。

查看 ld.so 的手册页 获取更多详细信息。

怎样处理多种架构

通常来说,32 位和 64 位版本的应用有不同的库。下面列表展示了不同 Linux 发行版库的标准路径:

红帽家族

  • 32 位:/usr/lib

  • 64 位:/usr/lib64

Debian 家族

  • 32 位:/usr/lib/i386-linux-gnu

  • 64 位:/usr/lib/x86_64-linux-gnu

Arch Linux 家族

  • 32 位:/usr/lib32

  • 64 位:/usr/lib64

FreeBSD(技术上来说不算 Linux 发行版)

  • 32 位:/usr/lib32

  • 64 位:/usr/lib

知道去哪找这些关键库可以让库链接失效的问题成为历史。

虽然刚开始会有点困惑,但是理解 Linux 库的依赖管理是一种对操作系统掌控感的表现。在其他应用程序中运行这些步骤,以熟悉常见的库,然后继续学习怎样解决任何你可能遇到的库的挑战。

“如何在 Linux 中使用动态和静态库”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 如何在 Linux 中使用动态和静态库

本文链接: https://www.lsjlt.com/news/280338.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在 Linux 中使用动态和静态库
    本篇内容介绍了“如何在 Linux 中使用动态和静态库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!了解 Linux 如何使用库,包括静态库...
    99+
    2023-06-15
  • 【Linux】静态库和动态库
    Linux为什么不允许普通用户给目录建立硬链接呢? 系统层面上有.和…硬链接指向目录。假设我们是超级用户,允许给目录建立硬链接,给根目录建立硬链接,从根目录开始查找,当查找硬链接的时候就是根目录,这...
    99+
    2023-09-07
    linux 服务器 运维
  • linux中怎么生成动态库和静态库
    linux中怎么生成动态库和静态库,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。动态库的生成:代码如下:#include <stdio.h>#include &...
    99+
    2023-06-09
  • Linux静态库与动态库如何制作
    这篇“Linux静态库与动态库如何制作”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Linux静态库与动态库如何制作”文章吧...
    99+
    2023-06-27
  • linux静态库和动态库的创建与使用方法
    这篇文章主要介绍“linux静态库和动态库的创建与使用方法”,在日常操作中,相信很多人在linux静态库和动态库的创建与使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”linux静态库和动态库的创建与使...
    99+
    2023-06-13
  • Linux动态库和静态库的示例分析
    今天就跟大家聊聊有关Linux动态库和静态库的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。函数库分为静态库和动态库两种。创建Linux静态库和Linux动态库和使用它们在这...
    99+
    2023-06-16
  • linux中动态库和静态库的区别有哪些
    这篇文章将为大家详细讲解有关linux中动态库和静态库的区别有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。区别:1、静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库;动态库在程序...
    99+
    2023-06-25
  • Linux静态函数库和动态函数库是什么
    这篇文章主要介绍“Linux静态函数库和动态函数库是什么”,在日常操作中,相信很多人在Linux静态函数库和动态函数库是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux静态函数库和动态函数库是什么...
    99+
    2023-06-28
  • GCC指令及动态库、静态库怎么使用
    本文小编为大家详细介绍“GCC指令及动态库、静态库怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“GCC指令及动态库、静态库怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、GCC1.1 GCC ...
    99+
    2023-07-04
  • C++静态库与动态库文件怎么生成和使用
    这篇文章主要介绍“C++静态库与动态库文件怎么生成和使用”,在日常操作中,相信很多人在C++静态库与动态库文件怎么生成和使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++静态库与动态库文件怎么生成和使用...
    99+
    2023-07-05
  • linux生成(加载)动态库静态库和加载示例方法
    动态库的生成: 1、 #include <stdio.h>#include "src.h" int sum(int a,int b){return (a+b);} 2、 #ifndef ...
    99+
    2022-06-04
    加载 示例 静态
  • Android静态库如何使用
    要使用Android静态库,需要按照以下步骤进行操作:1. 将静态库文件(通常是以`.a`或`.lib`为后缀)放在你的Androi...
    99+
    2023-08-23
    Android
  • Linux系统如何配置动态IP、静态IP
    这篇文章将为大家详细讲解有关Linux系统如何配置动态IP、静态IP,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 配置动态IP(dhcp)本例的操作系统是Centos 7。\1. 进入网络脚本配置目...
    99+
    2023-06-28
  • linux下静态链接库和动态链接库的区别有哪些
    这篇文章主要讲解了“linux下静态链接库和动态链接库的区别有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“linux下静态链接库和动态链接库的区别有哪...
    99+
    2023-02-07
    linux
  • 如何在PHP中实现静态页面动态化?
    随着互联网用户对于网页内容呈现的要求越来越高,动态页面技术已经成为了网页开发的标配。在一些较为简单的网站中,我们可以使用一些框架或者CMS系统来进行网站开发,实现快速开发并且轻松实现动态页面效果。不过一些小型的静态网站则需要手动实现动态化,...
    99+
    2023-05-23
    PHP缓存 PHP静态化 动态化页面
  • C++中Cmake的构建静态库和动态库是什么
    这篇文章主要为大家展示了“C++中Cmake的构建静态库和动态库是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C++中Cmake的构建静态库和动态库是什么”这篇文章吧。静态库和动态库的区别...
    99+
    2023-06-29
  • Linux中如何使用动态库函数
    这篇文章将为大家详细讲解有关Linux中如何使用动态库函数,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Linux动态库函数的详解加载动态库void *dlopen(const&n...
    99+
    2023-06-09
  • 如何在javascript中使用静态方法
    这篇文章将为大家详细讲解有关如何在javascript中使用静态方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。JavaScript的特点1.JavaScript主要用来向HTML页面添加...
    99+
    2023-06-14
  • 如何在java中使用静态方法
    如何在java中使用静态方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向...
    99+
    2023-06-14
  • GCC 指令详解及动态库、静态库的使用方法
    目录一、GCC1.1 GCC 介绍1.2 安装 GCC1.3 GCC 工作流程1.3.1 一般使用流程1.3.2 详细的工作流程1.4 GCC 常用参数1.4.1 指定一个宏(-D)...
    99+
    2022-11-13
    GCC 指令 GCC使用动态库 GCC使用静态库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作