什么是库

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于windows和Linux的本质不同,因此二者库的二进制是不兼容的。Linux操作系统支持的库函数分为静态库和动态库,动态库又称共享库。Linux系统有几个重要的目录存放相应的库函数,如/lib,/usr/lib;头文件放在/usr/include。

什么是静态库

静态库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库的支持,因为所有使用的函数都已经被编译进可执行文件了。当然这也会成为他的缺点,因为如何静态函数库改变了,那么你的程序必须重新编译,而且体积也比较大。

什么是动态库

动态库的名字一般是libxxx.so,相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用函数库里的相应函数,因此动态库函数所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。而且如果多个应用程序都要使用同一函数库,动态库就非常适合,可以减少应用程序的体积。

静态库的制作:

gcc -c file1.c

gcc -c file2.c

......

gcc -c fileN.c

ar -rcs libname.a file1.o file2.o ...... fileN.o

动态库制作:

gcc -shared -fpic -o libname.so file1.c file2.c  ...... fileN.c

编译:

动态库编译:gcc main.c -o test_li -Llib_patch -lname

静态库编译:gcc -static main.c -o test_li -Llib_patch -lname

(注:编译时出现提示错误:/usr/lib/ld:cannot find lc等错误查看链接:http://www.cnblogs.com/xiaohexiansheng/p/5500870.html)

案例:

 crypto.c
#include <stdio.h> void crypto(void)
{
printf("Start crypt..."); return ;
} crypto.h
#ifndef _CRYPTO_H_
#define _CRYPTO_H_ void crypto(void); #endif func.c
#include <stdio.h> void func(void)
{
printf("Start func..."); return ;
} func.h
#ifndef _FUNC_H_
#define _FUNC_H_ void func(void); #endif

生成静态库:

[xiaohexiansheng@centos6 test]$ ls
crypto.c  crypto.h  func.c  func.h  main.c
[xiaohexiansheng@centos6 test]$ gcc -c crypto.c -o crypto.o
[xiaohexiansheng@centos6 test]$ gcc -c func.c -o func.o
[xiaohexiansheng@centos6 test]$ ar -crs libcrypfunc.a crypto.o func.o
[xiaohexiansheng@centos6 test]$ ls
crypto.c  crypto.h  crypto.o  func.c  func.h  func.o  libcrypfunc.a  main.c

生成动态库:

[xiaohexiansheng@centos6 test]$ gcc -shared -fpic -o libcrypfunc.so crypto.c func.c
[xiaohexiansheng@centos6 test]$ ls
crypto.c  crypto.h  crypto.o  func.c  func.h  func.o  libcrypfunc.a  libcrypfunc.so  main.c

使用生成的动态库:

[xiaohexiansheng@centos6 test]$ gcc main.c -L. -lcrypfunc -o app

(注:-L指定函数库查找的位置,-L后面还有一个‘.’,表示在当前目录下寻找  -l指定库函数名,其中的lib和.a(.so)省略)
[xiaohexiansheng@centos6 test]$ ls
app  crypto.c  crypto.h  crypto.o  func.c  func.h  func.o  libcrypfunc.a  libcrypfunc.so  main.c
[xiaohexiansheng@centos6 test]$ ./app
./app: error while loading shared libraries: libcrypfunc.so: cannot open shared object file: No such file or directory
[xiaohexiansheng@centos6 test]$ pwd
/home/xiaohexiansheng/cc/library/test
[xiaohexiansheng@centos6 test]$ export LD_LIBRARY_PATH='/home/xiaohexiansheng/cc/library/test'
[xiaohexiansheng@centos6 test]$ ./app
Start crypt...Start func...[xiaohexiansheng@centos6 test]$

使用生成的静态库:

[xiaohexiansheng@centos6 test]$ ls
app  crypto.c  crypto.h  crypto.o  func.c  func.h  func.o  libcrypfunc.a  libcrypfunc.so  main.c
[xiaohexiansheng@centos6 test]$ gcc -static main.c -L. -lcrypfunc -o app
[xiaohexiansheng@centos6 test]$ ls
app  crypto.c  crypto.h  crypto.o  func.c  func.h  func.o  libcrypfunc.a  libcrypfunc.so  main.c
[xiaohexiansheng@centos6 test]$ ./app
Start crypt...Start func...[xiaohexiansheng@centos6 test]$

让我们看下静态库跟动态库的大小的区别:

[xiaohexiansheng@centos6 test]$ gcc main.c -L. -lcrypfunc -o sharedapp
[xiaohexiansheng@centos6 test]$ gcc -static main.c -L. -lcrypfunc -o staticapp

[xiaohexiansheng@centos6 test]$ du -sh sharedapp staticapp
8.0K    sharedapp
632K    staticapp

注意:

当静态库和动态库同时存在时,gcc默认使用的是动态库。如果强制使用静态库则加上-static选项。

动态库生成的可执行文件app不能正常运行是因为系统默认在/lib、/usr/lib下寻找动态库,如果想要程序正常运行可以把动态库放到这两个目录下的任意一个,或者按上面的那种方法 ---> LD_LIBRARY_PATH: 告诉系统执行程序的时候,除了/lib, /usr/lib以外还到哪里找动态库。

链接静态库的可执行文件比动态库的可执行文件要大很多。

参考链接:http://blog.chinaunix.net/uid-26833883-id-3219335.html

Linux 动态库 静态库的更多相关文章

  1. c/c++:动态库 静态库 linux/windows 例子 (转)

    作者:吴秦出处:http://www.cnblogs.com/skynet/本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名吴秦(包含链接). C++静 ...

  2. 在Linux中创建静态库.a和动态库.so

    转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...

  3. Linux 下动态库 / 静态库(依赖)

    一. 依赖动态库的动态库 libfun.so依赖动态库libtest.so(libfun.so动态库里的函数intnothing()调用了libtest.so里的intmytest()函数),而mai ...

  4. Linux库函数制作(静态库、动态库)

    Linux库函数制作(静态库.动态库) 静态库与动态库 链接方式 链接分为两种:静态链接.动态链接 静态链接: 由链接器在链接时将库的内容加入到可执行程序中 静态链接的特点是: 优点: 对运行环境的依 ...

  5. linux+vs2013编译静态库和动态库

    Linux下创建与使用静态库 Linux静态库命名规则 Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为 ...

  6. linux 动态库 静态库 函数覆盖

    本文讨论了linux动态库  静态库中函数的覆盖问题. 测试目的: 同名函数,分别打成动态库libdync_lib.so与静态库libstatic_lib.a,并把libstatic_lib.a打到另 ...

  7. linux下的静态库和动态库

    一.linux下的静态库   静态库中的被调用的函数的代码会在编译时一起被复制到可执行文件中去的!!可执行文件在运行不需要静态库的存在!   二.linux下动态库的构建和使用 1.动态库的构建   ...

  8. linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库

    linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库   创建静态库:ar -rcs test.a *.o查看静态库:ar -tv test.a解压静态库:ar -x test.a 查 ...

  9. Linux中的静态库与动态库

    什么是库文件? 库文件是事先编译好的方法的合集.比如:我们提前写好一些数据公式的实现,将其打包成库文件,以后使用只需要库文件就可以,不需要重新编写. Linux系统中: 1.静态库的扩展名为.a:2. ...

随机推荐

  1. 打印python的堆栈stack

    import sys def pstack(depth = 0): frame = sys._getframe(depth) cnt = 0 while frame: print "###& ...

  2. Hadoop安装过程

    1.安装JDK apt-get install openjdk-7-jdk 2.配置环境变量 vim /etc/profile 编辑: export JAVA_HOME=/usr/lib/jvm/ja ...

  3. gcc 簡單操作

    gcc -c test.c 產出 test.o object file gcc -c test.c -o XXX 產出 XXX object file gcc test.c -o aaa 產出 aaa ...

  4. chromium源代码下载(Win7x64+VS2013sp2, 39.0.2132.2)

    chromium源代码下载(Win7x64+VS2013sp2, 39.0.2132.2) http://www.aichengxu.com/diannao/1000251.htm 前后折腾了四天,当 ...

  5. Javacore分析(转载)

    本文转自(http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1406_tuzy_javacore/1406_tuz ...

  6. 【SQL】服务器环境下的SQL

    一.大型数据库的三层体系结构 web服务器:比如在淘宝页面上,输入“牛肉干”,就是web服务器来处理,提交给应用服务器. 应用服务器:在获取到“牛肉干”这个请求后,应用服务器决定如何汇集结果,并进行相 ...

  7. ACM-ICPC 2018 沈阳赛区网络预赛 D. Made In Heaven(第k短路模板)

    求第k短路模板 先逆向求每个点到终点的距离,再用dij算法,不会超时(虽然还没搞明白为啥... #include<iostream> #include<cstdio> #inc ...

  8. 51nod 最长公共子序列问题(动态规划)(LCS)(递归)

    最长公共子序列问题 输入 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) 输出 输出最长的子序列,如果有多个,随意输出1个. 输入示例 abcicba abdkscab 输 ...

  9. 【网络流】【Dinic】【Next Array】Dinic模板

    注意:有时加边不一定要加反向弧. Next Array版. #include<cstdio> #include<cstring> #include<algorithm&g ...

  10. 【分块】bzoj1798 [Ahoi2009]Seq 维护序列seq

    分块,打标记,维护两个标记:乘的 和 加的. 每次 区间乘的时候,对 乘标记 和 加标记 都 乘上那个值. 每次 区间加的时候 对 加标记 加上那个值. (ax+b)*v=axv+bv.开 long ...