`
东边日出西边雨
  • 浏览: 262789 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

静态库与共享库

    博客分类:
  • c
 
阅读更多

      在用c c++编程时经常用到库,库有静态的,和共享库。在这里我只是说linux系统下的静态库和共享库。有人把共享库称为“动态库”,这是相对于“静态库”而言的,是为了说明在程序链接它时的不同。不过从更宏观的层次上叫它共享库更贴切。

 

用例子说明吧:

 

现在有这几个文件:

 

                    zerg.h     zerg.cpp       hydralisk.h     hydralisk.cpp       

 

需要用库的形式提供。

 

制作静态库:

 

1.编译

 

 

gcc -c zerg.cpp hydralisk.cpp


 

 

编译出zerg.o hydralisk.o

然后用一个命令“ar”,把所有的.o文件打包,生成静态库libzerg.a

 

2.打包 

 

 

ar -qcs -o libzerg.a zerg.o hydralisk.o


 

 

 

总结:可见,静态库就是对一些.o文件的打包而已。只编译,不链接。提供静态库其实不太实用,一般都是提供共享库,如果需要调试的话,就直接提供源码好了。静态库的优势仅仅是比共享库效率高一小点。

 

制作共享库:

 

1.编译

 

g++ -fPIC -c zerg.cpp hydralisk.cpp


 

编译出zerg.o hydralisk.o。 和上面编译静态库时不同的是,需要指定"-fPIC"选项。 PIC(position indepedent code) , 共享库在运行时链接,不能预先知道装载的内存地址,所以要用-fPIC告诉编译器。

 

2. 链接

 

 

g++ -shared -o libzerg.so.1.0.0 zerg.o hydralisk.o


 

这样就生成了共享库libzerg.so.1.0.0

 

这两步都是用g++完成的,所以两步可以合成一步,如下命令可以直接把源码编译成共享库:

 

一步生成:

 

g++ -shared -fPIC -o libzerg.so.1.0.0 zerg.cpp hydralisk.cpp


 

共享库的版本控制:

 

 

 

 

 

 

 参考资料:

共享库的版本控制段落摘自:

http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246091138e0b924260d57938327365ff8540abdb6652969423db39bcc8849dbb8866d72c8713b3547da174f9658b8cb3732b12b872ae9b86893ad874484afa2c4af2044bd53127af1e7fb581763ce7880172693d18e49654860cefa466fe82f733eee27&p=c96ad615d9c044e90be290121100&user=baidu&fm=sc&query=windows+%B9%B2%CF%ED%BF%E2+%B0%E6%B1%BE%BF%D8%D6%C6&qid=d6505642138c09ac&p1=10

 

linux下的so文件不具有像windows下的额外属性。为了标识一个so的版本,gcc链接生成so目标时一般都采用libxxx.so.1.0.0的方式。

这样把so的版本信息记录在文件名里面。这个带版本信息的文件名就是realname。

 

那么exe可执行文件如何记录自己依赖的so呢,如果记录的是so的realname,那么so有新版本升级时,新的so必定具有不同的realname,exe就无法自动使用更新的so了。

好在linux下有软链这样的机制可以解决该问题。exe中不必记录依赖的so的realname,exe中记下一个指向实际realname的软链即可,这个软链就是soname啦。soname一般采用这样的名字 libxxx.so.1(保留大版本号1)

当有一个功能更新的so发布时,只需修改soname软链,指向升级后的realname文件即可。

比如我发布了xxx动态库的升级版 libxxx.so.1.0.1, 使软链libxxx.so.1指向libxxx.so.1.0.1即可。

soname是我们在编译其他程序时,往其他程序的二进制映像里面写入的共享库的名字。

 

那么什么是linkname呢?顾名思义,就是编译代码时的链接阶段使用的,比如我有一个程序需要链接libxxx.so.1.0.0库,

makefile需这样写 -lxxx.so.1.0.0,这r样写实在很长也很丑,而且如果后续libxxx有更新时,必须修改makefile文件才能链接到新的库上。

所以出现了一个新的链接到realname的软链,这个软链就叫 linkername。通常lingkername是不带任何版本信息的,取名如下 libxxx.so

这样makefile就变成了 -lxxx.so

 

这其中有一个问题,动态库的使用者(比如exe)是通过linkername链接的,而lingkername指向的是so的realname,我们前文说为了解决升级so重新编译的问题,exe文件里面记录的是其依赖的so的soname名字,而不是真实的realname,

那么exe是如何知道realname对应的soname呢?

答案在realname文件里面,在编译链接生成realname时, 同事也指定了其对应的soname,这个soname存储在realname的文件里面。

eg 如下编译命令:

gcc -g -Wall -shared -Wl,-soname,liberr.so.1 -o liberr.so.1.0.0 liberr.o -lc  // liberr.so.1是soname,将记录在生成的liberr.so.1.0.0文件里面

可以通过如下工具查看一个realname的so的对应的soname:

readelf -d ./liberr.so.1.0.0 

Dynamic section at offset 0xf10 contains 22 entries:

  Tag        Type                         Name/Value

 0x00000001 (NEEDED)                     Shared library: [libc.so.6]

 0x0000000e (SONAME)                     Library soname: [liberr.so.1] ===============< 其soname

 

分享到:
评论

相关推荐

    linux静态库和共享库.pdf

    在Linux操作系统中,库扮演着至关重要的角色,它们是预先编译的代码集合,允许开发者重用和集成已经实现的功能,而无需从零开始编写代码。...理解和掌握静态库与共享库的使用和管理对于任何Linux开发者都是至关重要的。

    静态库和动态库里的全局变量(或类的静态成员变量)共享和独立的问题

    1. 工程中包含静态库A,动态库B,可执行程序C。C依赖于A和B,而B依赖于A。在A中定义有全局变量X(或类的静态成员变量),则在动态库B中访问的X,与可执行程序C中访问的X是同一个变量还是两个不同的变量? 答案:是两...

    静态库和动态库_共享库

    库通常分为两种主要类型:静态库和动态库(共享库)。这两种库各有优缺点,适用于不同的场景。 静态库,通常以.lib文件格式存在,其特点是将库中的函数和数据直接嵌入到最终的可执行文件中。这意味着当编译程序时,...

    静态库、共享库、动态库的创建和使用.txt

    ### 静态库、共享库、动态库的创建与使用 #### 一、静态库的理解与使用 **定义:** 静态库(Static Library)是一系列预编译的目标文件(Object Files)的集合,通常以`.a`为扩展名。在程序链接阶段,链接器会根据...

    GCC静态库和共享库的生成及调用

    GCC 静态库和共享库的生成及调用 GCC 编译器为我们提供了两种类型的库:静态库(archive,扩展名.a)和共享库(又叫动态库,扩展名.so)。无论是静态库还是共享库,都是由.o 文件创建的。每个.o 文件都包含这个编译...

    Qt静态库与动态库创建与演示

    本教程将深入探讨如何在Windows XP环境下,利用Qt 4和MinGW编译器创建和使用静态库与动态库。 首先,让我们理解静态库和动态库的基本概念。静态库(.lib文件)是将库函数编译到目标代码中,形成一个完整的可执行...

    linux静态库和动态库

    ### Linux静态库与动态库详解 #### 一、引言 在Linux环境下,库是一种重要的软件组件,用于封装一组相关的函数或数据结构,以便于在不同的应用程序之间共享代码。库通常分为两大类:静态库(static libraries)和...

    linux 动态库静态库

    创建静态库的流程与动态库类似,但不需要最后一步生成动态库。使用静态库的程序在运行时体积较大,但不受系统动态库版本影响。 使用动态库和静态库的方式有所不同。对于动态库,需要确保目标系统上已经安装了相应的...

    opencv-1.1静态库

    标题提到的"opencv-1.1静态库"是针对早期OpenCV 1.1版本的一个特殊构建,通常OpenCV会提供动态库(.dll文件),但在这个情况下,提供了静态库(.lib文件)。 静态库和动态库是两种不同的库文件类型。静态库在编译时...

    cmakelists 生成静态库,然后用静态库生成动态库,然后生成测试程序

    本篇将深入探讨如何使用CMakeLists来生成静态库、动态库,并创建测试程序进行验证。 首先,我们要理解静态库和动态库的区别。静态库(.a 或 .lib)是在编译时将库代码直接嵌入到目标程序中,形成一个完整的可执行...

    liunx静态库与动态库链接装载与库.zip

    本资料主要探讨的是Linux中的静态库与动态库的链接装载过程,以及如何理解和使用它们。 静态库,通常以`.a`文件格式存在,它将所有依赖的代码直接嵌入到目标程序中。当编译程序时,链接器会将静态库中的函数和数据...

    librdkafka 动态库 静态库

    3. **动态库与静态库**: - **动态库**(.dll文件):在程序运行时由操作系统加载,多个程序可以共享同一份库副本,节省内存。但是,动态库的缺失或版本不匹配可能导致运行时错误。 - **静态库**(.lib文件):在...

    静态库工具.rar 易语言 动态转静态库

    动态库(Dynamic Link Library,简称DLL)是一种共享库,程序运行时才加载到内存中,多个程序可以共享同一份库的拷贝,节省内存。而静态库(Static Library)则是在编译时将库代码直接链接到目标程序中,使得程序...

    动态库静态库测试依赖问题的demo

    - 静态库:每个使用静态库的程序都有库的副本,可能导致更大的内存占用,但避免了共享库可能导致的竞争条件或同步问题。 **3. 体积与发布**: - 动态库:生成的可执行文件较小,便于分发,但需要确保目标环境有...

    静态库_动态库生成过程及其调用方法详解

    与静态库不同,动态库在运行时被加载到进程内存中,多个程序可以共享同一份库文件,节省系统资源。当程序运行时,需要动态库的函数和数据是在运行时通过动态链接器(Loader)加载的。动态库的文件扩展名通常是.dll或...

    linux静态库的生成与使用

    ### Linux静态库的生成与使用 #### 一、概述 在Linux环境下,静态库是一种非常重要的资源管理方式,它能够帮助开发者将多个模块或者组件整合到一个可重用的库中,进而提升软件开发的效率和质量。本文将详细介绍...

    openSSL头文件和静态库文件以及动态库

    与静态库相比,动态库可以减少内存占用,多个程序可以共享同一份库代码。但在Windows系统上,如果目标机器缺少相应的动态库,程序可能无法运行。因此,当使用动态库时,记得将它们部署到系统路径或应用程序目录下。 ...

    关于在Linux平台上接静态库和共享库的使方法.docx

    Linux平台上静态库和共享库的使用方法 Linux 函数库介绍 函数库可以看做是事先编写的函数集合,它可以与主函数分离,从而增加程序开发的复用性。Linux 中函数库可以有 3 种使用的形式:静态、共享和动态。 静态库...

Global site tag (gtag.js) - Google Analytics