分享

Linux下静态链接库和动态链接库的使用

 rookie 2012-04-09

    库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。 例如:libtest.so libtest.a。为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,但由于程序连接默认以.so为文件后缀名。所以为了使用这些 库,通常使用建立符号连接的方式。如:

    ln -s libtest.so.1.0 hello.so.1

    ln -s libtest.so.1 hello.so    下面对比一下两者:

    静态链接库:当要使用时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。

    动态库而言:某个程序在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则 让其共享那一个拷贝;只有没有才链接载入。在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此, 这些代码必须使用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址不无关代码 (Position Independent Code (PIC))。注意:linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。

    下面就通过实际的例子来向大家演示一下,该怎样编译和使用静态和动态链接库,这里有一个头文件:lib_test.h,一个.c文件:lib_test.c:

       1.编写库文件lib_test.c            2.编写一个头文件用于声明我们使用的函数lib_test.h        3.用gcc编绎该文件,可以使用任何合法的编绎参数
         #include<stdio.h>                #ifndef _LIBTEST_H                                               gcc -c lib_test.c -o lib_test.o
         void a()                             #define _LIBTEST_H
         {                                      void a();
             printf("zyx\n");               #endif
         }

    下面就用上面的文件生成和使用静态和动态链接库:
    (一)静态链接库          

      1)用gcc编绎该文件,可以使用任何合法的编绎参数
          gcc -c lib_test.c -o lib_test.o

      2) $ar crv libtest.a lib_test.o   //生成静态库生成libtest.a

      3) 在某些系统中还要为静态库生成一个内容表   $ranlib libtest.a

      4) 使用静态链接库

        $nm libtest.a    //nm工具可以打印出库中的涉及到的所有符号,库既可以是静态的也可以是动态的。nm列出的符号有很多, 常见的有三种,一种是在库中被

                             调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的"弱态”

                             符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。

        $gcc -c -I/home/xxxxxxxx main.c //假设main.c要使用对应的静态库

        $gcc -o main -L/home/xxxxxxxx main.o libtest.a

     说明:这里的-I/home/xxxxxxxx和-L/home/xxxxxxxx 是通过-I和-L指定对应的头文件和库文件的路径,libtest.a就是要用的静态库。在main.c中要包含静态库

     的头文件。

     5)然后执行程序就可以看到成功了。#./main

   (二)动态链接库 可以依次使用下面的命令

     1)$gcc -fPIC -o libtest.o -c lib_test.c

     2)$gcc -shared -o libtest.so libtest.o   

        也可以直接使用一条命令gcc -fPIC -shared -o libtest.so lib_test.c

     3)有两种方法使用动态链接库。

       a)#gcc -o main main.c ./libtest.so

       b)先#cp ./libtest /usr/lib 然后gcc -o test test.c libtest.so这时要保证这个库所在目录包括再PATH 环境变量中。

     4)然后执行程序就可以看到成功了。#./main  

   最后说一下库的路径问题,算是结个尾吧:

   动态库的搜索路径搜索的先后顺序是:

     1.编译目标代码时指定的动态库搜索路径;

     2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

     3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;//只需在在该文件中追加一行库所在的完整路径如"/root/test/conf/lib"即可,然后ldconfig是修改生效。

     4.默认的动态库搜索路径/lib;

     5.默认的动态库搜索路径/usr/lib。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多