linux下的静态链接库和动态链接库总结

来源:互联网 发布:sqlserver添加字段 编辑:程序博客网 时间:2024/06/04 01:00
这几天读了几篇关于linux下静态库和动态库的文章,想总结一下:
声明 :本文例子以及大部分内容参考以下网络博文
http://blog.csdn.net/muge0913/article/details/7308140
http://blog.csdn.net/muge0913/article/details/7308178
http://www.cnblogs.com/fence/archive/2009/09/29/1576503.html 


注:例子所在目录分别为/home/code/C_Pro/staticlib和 /home/code/C_Pro/Danmiclib
现在假设有文件foo.c和bar.c以及头文件foobar.h
/**********************************foobar.h*******************************************/

#ifndef _FOOBAR_H_
#define _FOOBAR_H_
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
extern char* foo(void);        
extern char* bar(void);
#endif
/**********************************foobar.h*******************************************/


#include"foobar.h"
char* bar(void)
{
  printf("This is bar!library1 is called\n");
  return("bar");

 /***********************************bar.c*****************************************/


 /***********************************foo.c*****************************************/ 
#include"foobar.h"
char* foo(void)
{
  printf("This is foo! library2 is called\n");
  return ("foo");
}

/***********************************foo.c*****************************************/ 

一、建立和使用静态链接库,在linx中为.a文件,所用到的工具是ar命令。
1.在建立了foo.c,bar.c,foobar.h三个文件之后需要执行
  #gcc -c foo.c -o foo.o
  #gcc -c bar.c -o bar.o
  #ar rcs libfoobar.a foo.o bar.o
 以生成foo.o,bar.o,libfoobar.a三个文件。其中libfoobar.a就是我们的静态库文件
2.我们想调用bar.c和foo.c定义的函数,比如在main.c中调用,在main.c文件中可以直接调用
  只是在编译的时候需要如下操作:
  gcc -o foobar.exe mian.c libfoobar.a
  就可以了 
说明:(以下说明引用自网上博文)
1.    ar比较经常用到的就是有三个命令选项:r(插入)、c(创建)和s(建立索引),而且这三个选项往往是一起使用。参数r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。参数c:创建一个库。不管库是否存在,都将创建。参数s:创建目标文件索引,这在创建较大的库时能加快时间。(补充:如果不需要创建索引,可改成大写S参数;如果。a文件缺少索引,可以使用ranlib命令添加)

2.  静态链接库是一种“复制式”的链接过程。何谓“复制式”的链接过程呢,当静态链接库与应用程序链接时,链接器会将静态链接库复制一份到最终得到的可执行代码中去。比如:现在有两个应用程序A和B,两者都要用到libfoobar.a所提供的功能。那么,在编译链接A时,链接器将复制一份libfoobar.a到A最终的可执行代码中去,libfoobar.a中的调试信息也会被复制,同样,在链接B时,链接器也会复制一份libfoobar.a到B最终的可执行代码中去。这就是“复制式”链接的意义。

查看foobar程序用到的动态链接库:

 
二、动态链接库的建立和使用
有了bar.c、foo.c、foobar.h以及main.c三个文件之后---
方法一:
    (1).在建立了foo.c,bar.c,foobar.h三个文件之后需要执行(我们要调用的函数在两个.c文件中分别定义,
     在.h文件中声明为external)
       #gcc -c foo.c -o foo.o
       #gcc -c bar.c -o bar.o
   (2).创建动态链接库:
       #gcc –shared –Wall –fPIC bar.o foo.o –o libfoobar.so 
 
方法二:
 # 声称动代连接库,假设名称为libtest.so
 gcc foo.c bar.c -fPIC -shared -o libfoobar.so
 # 将main.c和动态连接库进行连接生成可执行文件
创建一个main.c文件,其工作是调用foo.c和bar.c中定义的函数
在创建了libxxx.so动态库之后,通过以下方式生成可执行文件main.exe
 gcc main.c -L. -lfoobar -o main.exe

但是一般情况下会找不到.so文件Linux中绝大多数.so文件都存放在/lib、/usr/lib/(见Linux目录结构),
   对于64位和32位共存的系统,32位的动态库可能会放在/lib32、/usr/lib32,完整的动态库存放路径列表
   可通过/etc/ld.so.conf文件配置。(如果修改了配置,需要用 /sbin/ldconfig 命令更新缓存)应注意动
   态库搜寻路径并不包括当前文件夹,所以当即使可执行文件和其所需的so文件在同一文件夹,也会出现找不到
   so的问题.
此时可以有两种解决方法:
方法一:
  用LD_LIBRARY_PATH环境变量做临时设置,如下:
  LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./Danmiclib
方法二:
  在/etc/ld.so.conf配置文件中添加动态libfoobar.so库所在目录,在本例中采用此方法,/etc/ld.so.conf配置修改如下
  所示:
  从原文件:
  include /etc/ld.so.conf.d/*.conf 改为
  include /etc/ld.so.conf.d/*.conf
         /home/code/C_Pro/Danmiclib
这样就可以了。

# 测试是否动态连接,如果列出libfoobar.so,那么应该是连接正常了
ldd main.exe
 
附上一些参数含义:
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来
 满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中
-lfoobar:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
运行环境:unix/linux
工具:gnu,gcc
原创粉丝点击