【技术篇】静态库和动态库 您所在的位置:网站首页 linux动态库和静态库的使用方法一样吗 【技术篇】静态库和动态库

【技术篇】静态库和动态库

2024-07-17 12:26| 来源: 网络整理| 查看: 265

(一)库是什么

      本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。通俗的来说库是一组预先编译好的函数的集合,这些函数都是按照可重用的原则编写的。在库中的函数是相互关联的,通过这些函数的组成可以实现相应的功能。

(二)库的种类

     库分为静态库和共享库(共享库又叫动态库)。 二者的不同点在于代码被载入的时刻不同。静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

(三)动态库和静态库的使用   静态库

         程序在编译阶段,会将引用到的库中的左右内容复制到程序中,然后在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。

      静态库特点总结:

    (1)静态库对函数库的链接是放在编译时期完成的。

    (2)程序在运行时与函数库再无瓜葛,移植方便。

    (3)浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

  动态库

         库动态库是在程序运行时被载入引用。   只在程序中做一个标记,当用到被标记的库中的函数时,程序会顺着做的标记找到库,然后调用需要的函数,并不会像静态库一样将库中的所有内容都复制包含进来。

为什么有了静态库还要设计动态库?

        首先是空间浪费是静态库的一个问题。我们可以这样想假如某一个人静态库占用1M内存,此时有2000个这样的程序需要用到这个库,那么此时,每个程序都需要将这个静态库中的内容拷贝一份到自己里面,这样内存中就会产生多分库函数,并且这些会占用将近2GB的空间。

        另外一个问题是由于静态库对程序的更新、部署和发布带来的麻烦。假如某一个静态库更新了,所有使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,只是一个小小的改动,但是却会导致整个程序重新下载,全量更新)

        因此我们需要引入动态库,由于动态库是程序运行时被载入的,不同的程序如果调用相同的库,在内存中里只需要有一份该库的实例,避免了空间的浪费,同时也解决了静态库对程序的更新、部署和发布带来的麻烦,用户只需要更新动态库即可,增量更新。

       动态库特点总结:

       (1)动态库把对一些库函数的链接载入推迟到程序运行的时期。 

       (2)可以实现进程之间的资源共享。(因此动态库也称为共享库)

       (3)将一些程序升级变得简单。

       (4)甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。 

(四)库的创建和使用 创建静态库

    (1)Linux静态库命名规则:Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。

    (2)创建静态库(.a)

第一步将代码文件编译成目标文件.o(StaticMath.o)

g++ -c StaticMath.cpp //注意带参数-c,否则直接编译为可执行文件

第二步通过ar工具将目标文件打包成.a静态库文件

ar -crv libstaticmath.a StaticMath.o //生成静态库libstaticmath.a 

注:ar的用法如下

(1)ar是什么   ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。   ar命令格式:ar [-] {dmpqrtx} [abcfilNoPsSuvV] [membername] [count] archive files...   例如我们可以用ar rv libtest.a hello.o hello1.o来生成一个库,库名字是test,链接时可以用-ltest链接。该库中存放了两个模块hello.o和hello1.o。选项前可以有‘-'字符,也可以没有。下面我们来看看命令的操作选项和任选项。现在我们把{dmpqrtx}部分称为操作选项,而[abcfilNoPsSuvV]部分称为任选项。 【注:ar可让您集合许多文件,成为单一的备存文件。在备存文件中,所有成员文件皆保有原来的属性与权限】(2)参数介绍

指令参数

        -d  删除库文件中的成员文件。         -m  变更成员文件在库文件中的次序。         -p  显示库文件中的成员文件内容。         -q  将问家附加在库文件末端。         -r  将文件插入库文件中。         -t  显示库文件中所包含的文件。         -x  自库文件中取出成员文件。

选项参数

        a  将文件插入库文件中指定的成员文件之后。         b  将文件插入库文件中指定的成员文件之前。         c  建立库文件。         f  为避免过长的文件名不兼容于其他系统的ar指令指令,因此可利用此参数,截掉要放入库文件中过长的成员文件名称。         i  将问家插入库文件中指定的成员文件之前。         o  保留库文件中文件的日期。         s  若库文件中包含了对象模式,可利用此参数建立备存文件的符号表。         S  不产生符号表。         u  只将日期较新文件插入库文件中。         v  程序执行时显示详细的信息。         V  显示版本信息。

      ar用来管理一种文档。这种文档中可以包含多个其他任意类别的文件。这些被包含的文件叫做这个文档的成员。ar用来向这种文档中添加、删除、解出成员。成员的原有属性(权限、属主、日期等)不会丢失。实际上通常只有在开发中的目标连接库是这种格式的,所以尽管不是,我们基本可以认为ar是用来操作这种目标链接库(.a文件)的。

(3)ar的常用用法

创建库文件

         我不知道怎么创建一个空的库文件。好在这个功能好像不是很需要。通常人们使用“ar cru liba.a a.o"这样的命令来创建一个库并把a.o添加进去。"c"关键字告诉ar需要创建一个新库文件,如果没有指定这个标志则ar会创建一个文件,同时会给出 一个提示信息,"u"用来告诉ar如果a.o比库中的同名成员要新,则用新的a.o替换原来的。但是我发现这个参数也是可有可无的,可能是不同版本的ar 行为不一样吧。实际上用"ar -r liba.a a.o"在freebsd5上面始终可以成功。

加入新成员

       使用"ar -r liba.a b.o"即可以将b.o加入到liba.a中。默认的加入方式为append,即加在库的末尾。"r"关键字可以有三个修饰符"a", "b"和"i"。  "a"表示after,即将新成员加在指定成员之后。例如"ar -ra a.c liba.a b.c"表示将b.c加入liba.a并放在已有成员a.c之后;  "b"表示before,即将新成员加在指定成员之前。例如"ar -rb a.c liba.a b.c"; "i"表示insert,跟"b"作用相同。

列出库中已有成员

      "ar -t liba.a"即可。如果加上"v"修饰符则会一并列出成员的日期等属性。

删除库中成员

      "ar -d liba.a a.c"表示从库中删除a.c成员。如果库中没有这个成员ar也不会给出提示。如果需要列出被删除的成员或者成员不存在的信息,就加上"v"修饰符。

从库中解出成员

     "ar -x liba.a b.c"

调整库中成员的顺序

      使用"m"关键字。与"r"关键字一样,它也有3个修饰符"a","b", "i"。如果要将b.c移动到a.c之前,则使用"ar -mb a.c liba.a b.c"

使用静态库

         编写使用上面创建的静态库的测试代码:

#include "StaticMath.h" #include using namespace std; int main(int argc, char* argv[]) { double a = 10; double b = 2; cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有