Linux_4. 静态库和共享库

Linux_4. 静态库和共享库

  1. 库的定义

     本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于windows 和 linux 的本质不同,因此二者库的二进制是不兼容的。
    
  2. 分类

     Linux 操作系统支持的函数库分为静态库和动态库,动态库又称共享库。
     Linux 系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。
    
  3. 区别

     A. 这类库的名字一般是 libxxx.a;
       利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都被整合进目标代码中;
       优点:即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进可执行文件了。
       缺点:因为如果静态函数库改变了,那么你的程序必须重新编译,而且体积也较大。
    
     B.这类库的名字一般是 libxxx.so,动态库又称共享库;
       优点:
         1.动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。
         2.如果多个应用程序都要使用同一函数库,动态库就非常适合,可以减少应用程序的体积。
       缺点:
         1.由于函数库没有被整合进你的程序,而是程序运行时动态申请并调用,所以程序的运行环境中必须提供相应的库。
         2.相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。
    
     注意:不管是静态函数库还是动态函数库,都是由*.o 目标文件生成。
    
  4. 函数库的创建

     A.静态函数库的创建
         ar -cr libname.a test1.o test2.o
         ar:静态函数库创建的命令
         -c :create 的意思
         -r :replace 的意思,表示当前插入的模块名已经在库中存在,则替换同名的模块。如果若
         干模块中有一个模块在库中不存在,ar 显示一个错误信息,并不替换其他同名的模块。默认的情况下,新的成员增加在库的结尾处。
    

     B.动态函数库的创建
         gcc -shared -fpic -o libname.so test1.c test2.c
         -fpic:产生代码位置无关代码
         -shared :生成共享库
    

     其中
     -L 指定函数库查找的位置,注意 L 后面还有'.',表示在当前目录下查找
     -l 则指定函数库名,其中的 lib 和.a(.so)省略。
     注意:-L 是指定查找位置,-l 指定需要操作的库名。
    
  • 从上面的运行结果中,我们可以看到:
      A.当动态库和静态库同时存在的时候,gcc 默认使用的是动态库。如果强制使用静态库则需
      要加-static 选项支持。
      B.动态库生成的可执行文件,test1 不能正常的运行。
      C.链接静态库的可执行程序明显比链接动态库的可执行文件大。
    

5 静态库和动态库的使用
 实例:

add.c
#includ 
int add(int a,int b)
{
    return a + b;
}

sub.c
#include 
int sub(int a,int b)
{
return a - b;
}

head.h
#ifndef _HEAD_H_
#define _HEAD_H_
extern int add(int a,int b);
extern int sub(int a,int b);
#endif

main.c
#include
int main(int argc,char *argv[])
{
    int a,b;
    if(argc < 3)
    {
        fprintf(stderr,"Usage : %s argv[1] argv[2].\n",argv[0]);
        return -1;
    } 
    a= atoi(argv[1]);
    b = atoi(argv[2]);
    printf("a + b = %d\n",add(a,b));
    printf("a - b = %d\n",sub(a,b));
    return 0;
}

6 链接动态库的可执行程序正常运行的解决方法?

  • 原因:当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路劲。此时就需要系统动态载入器(dynamic linker/loader)。
    对于 elf 格式的可执行程序,是由 ld-linux.so*来完成的,它先后搜索 elf 文件的
    DT_RPATH 段---环境变量 LD_LIBRARY_PATH、/etc/ld.so.cache 文件列表、/usr/lib、/lib
    目录找到库文件后将其载入内存。

  • 解决方法
    A.一种最直接的方法,就是把生成的动态库拷贝到/usr/lib 或/lib 中去。

    B.使用 LD_LIBRARY_PATH 环境变量,这个环境变量在 ubuntu 操作系统中默认没有,需要手
    动添加

    C.动态在安装在其他目录下,如果想操作系统能找到它,可以通过一下步骤

    <1>新建并编辑/etc/ld.so.conf.d/my.conf 文件,加入库所在目录的路径
    <2>执行 ldconfig 命令更新 ld.so.cache 文件

      此时,在执行链接动态库的可执行文件则可以正常运行。
    

7 查看库中的符号

A.nm 命令可以打印出库中涉及到的所有符号。库既可以是静态库也可以是动态的。
常见的三种符号:
    <1>在库中被调用,但没有在库中定义(表明需要其他库支持),用 U 表示
    <2>在库中定义的函数,用 T 表示
    <3>“弱态”符号,他们虽然在库中被定义,但是可能被其他库中同名的符号覆盖,用 W 表
    示。

B.ldd 命令可以查看一个可执行程序依赖的共享库
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值