Chinaunix首页 | 论坛 | 博客
  • 博客访问: 686087
  • 博文数量: 111
  • 博客积分: 2109
  • 博客等级: 上尉
  • 技术积分: 1124
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-25 12:11
个人简介

通信码农,Emacs爱好者,业余IOS程序员,更业余的PM

文章分类

全部博文(111)

文章存档

2018年(2)

2016年(2)

2015年(2)

2014年(13)

2013年(21)

2012年(71)

分类: LINUX

2012-09-12 19:36:35

库有动态与静态两种,动态通常用.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 #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。
阅读(2068) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~