`
东边日出西边雨
  • 浏览: 258127 次
  • 性别: 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

 

分享到:
评论

相关推荐

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

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

    linux静态库和共享库.pdf

    linux静态库和共享库.pdf

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

    静态库就是一些目标文件的集合,以.a结尾。静态库在程序链接的时候使用,链接器会将程序中使用 到函数的代码从库文件中拷贝到应用程序中。一旦链接完成,在执行程序的时候就不需要静态库了。 由于每个使用静态库...

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

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

    静态库和动态库_共享库

    .dll是在你的程序运行的时候才连接的文件,因此它是一种比较小的可执行文件格式,.dll还有其他的文件格式如.ocx等,所有的.dll文件都是可执行。

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

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

    学习C++动态库静态库的使用

    一般静态库、动态库的创建和使用 (非 MFC 动态库) 总结解决方案的学习内容: 1.静态库的创建和使用 2.动态函数库的创建及使用 3.动态库的动态调用和静态调用 4.动态库导入、出全局共享变量 5.动态库导入、出类

    动态库与静态库区别

    静态库和共享库(动态库)。 二者的不同点在于代码被载入的时刻不同。 } 静态库在程序编译时会被连接到目标代码中,程序运行 时将不再需要该静态库,因此体积较大。 } 动态库在程序编译时并不会被连接到目标代码中,...

    Linux静态库和动态库的分析及实现

     linux下的库有两种:静态库和共享库(动态库)。  二者的不同点在于代码被载入的时刻不同。  静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。  共享库的代码是在可执行程序运行时才载入内存...

    gcc编译C++共享库/静态库供C调用的简单例子

    C++编写的共享库,用gcc编译连接,分别生成.so和.a,C编写的main,用gcc编译,连接.so和.a调用的简单例子

    Windows Mobile下用的SQlite3静态库源码

    带C++Wrapper实现,在项目中用到,共享出来。

    【Linux】静态库和动态库

    Linux下,库分为静态库和共享库。   库的生成 静态库:库名:Libxxx.a,lib是库的前缀,xxx是库名,.a为静态库的后缀。 第一步:将需要生成静态库的.c文件转换为编译后的.o文件 命令:gcc -S mian.o mian.c 第二步...

    IOS 静态库和Framework区别

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

    openscenegraph(osg)3.2.1rc1 android静态库 http://521.be

    原来在这里发布过一版,在成功编译示例以后没有运行测试就传上来了,后来自己导入模型后发现不能正常显示,现又编译一版,为gles1.0版本,解压后大概有4g。 ... 编译结果为 include+obj的形式,dome实例参考官方源码...

    iOS全局自动化 代码混淆 工具,静态库方法和系统库方法!.zip

    支持cocoapod组件代码一并 混淆,完美避开hardcode方法、静态库方法和系统库方法! 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动应用开发、网站开发C++、Java、python、web、C#等语言的项目开发与学习...

    Linux C语言动态库及静态库的制作步骤讲解

    假设在math目录下已编辑好add.c sub.c div.c mul.c func_point.c文件,func_...  gcc -shared -o libmymath.so add.o sub.o mul.o div.o//创建共享库mymath,添加add.o,sub.o,mul.o,div.o目标文件  sudo m

    Linux下编译静态库和动态库1

    1.创建共享库 2.编译共享库 1.环境变量

    C语言静态函数库的制作和使用方法

    作者:杨硕,华清远见嵌入式学院讲师。  一.库函数简介:  C语言中有一些函数会执行一些标准任务,可以事先对这些函数进行编译,然后将他们放置在一些特殊的...共享库  二.静态库:  1)基本概念:  静态库

    ios静态库问题

    共享ios制作静态类库的过程经验,遇到的问题和解决的方法

    VC++写动态链接库教程

    静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”...

Global site tag (gtag.js) - Google Analytics