静态库和动态库

静态库和动态库

引言

    将多个目标文件打包到一起,形成一个文件,叫库
    库文件名字都是以lib开头的
    本次我们将《UNIX环境高级编程》(第三版)的error.c源码打包成静态库或者动态库
  1. #ifndef __ERROR_H__
  2. #define __ERROR_H__
  3. /**
  4. * Nonfatal error related to a system call.
  5. * Print a message and return.
  6. */
  7. void err_ret(constchar*fmt,...);
  8. /**
  9. * Fatal error related to a system call.
  10. * Print a message and terminate.
  11. */
  12. void err_sys(constchar*fmt,...);
  13. /**
  14. * Nonfatal error unrelated to a system call.
  15. * Error code passed as explict parameter.
  16. * Print a message and return.
  17. */
  18. void err_cont(int error,constchar*fmt,...);
  19. /**
  20. * Fatal error unrelated to a system call.
  21. * Error code passed as explict parameter.
  22. * Print a message and terminate.
  23. */
  24. void err_exit(int error,constchar*fmt,...);
  25. /**
  26. * Fatal error related to a system call.
  27. * Print a message, dump core, and terminate.
  28. */
  29. void err_dump(constchar*fmt,...);
  30. /**
  31. * Nonfatal error unrelated to a system call.
  32. * Print a message and return.
  33. */
  34. void err_msg(constchar*fmt,...);
  35. /**
  36. * Fatal error unrelated to a system call.
  37. * Print a message and terminate.
  38. */
  39. void err_quit(constchar*fmt,...);
  40. #endif/* __ERROR_H__ */
代码1 error.h头文件
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<errno.h>/* for definition of errno */
  5. #include<stdarg.h>/* ISO C variable aruments */
  6. #include"error.h"
  7. #define MAXLINE 4096/* max line length */
  8. staticvoid err_doit(int,int,constchar*, va_list);
  9. void err_ret(constchar*fmt,...)
  10. {
  11. va_list ap;
  12. va_start(ap, fmt);
  13. err_doit(1, errno, fmt, ap);
  14. va_end(ap);
  15. }
  16. void err_sys(constchar*fmt,...)
  17. {
  18. va_list ap;
  19. va_start(ap, fmt);
  20. err_doit(1, errno, fmt, ap);
  21. va_end(ap);
  22. exit(1);
  23. }
  24. void err_cont(int error,constchar*fmt,...)
  25. {
  26. va_list ap;
  27. va_start(ap, fmt);
  28. err_doit(1, error, fmt, ap);
  29. va_end(ap);
  30. }
  31. void err_exit(int error,constchar*fmt,...)
  32. {
  33. va_list ap;
  34. va_start(ap, fmt);
  35. err_doit(1, error, fmt, ap);
  36. va_end(ap);
  37. exit(1);
  38. }
  39. void err_dump(constchar*fmt,...)
  40. {
  41. va_list ap;
  42. va_start(ap, fmt);
  43. err_doit(1, errno, fmt, ap);
  44. va_end(ap);
  45. abort();/* dump core and terminate */
  46. exit(1);/* shouldn't get here */
  47. }
  48. void err_msg(constchar*fmt,...)
  49. {
  50. va_list ap;
  51. va_start(ap, fmt);
  52. err_doit(0,0, fmt, ap);
  53. va_end(ap);
  54. }
  55. void err_quit(constchar*fmt,...)
  56. {
  57. va_list ap;
  58. va_start(ap, fmt);
  59. err_doit(0,0, fmt, ap);
  60. va_end(ap);
  61. exit(1);
  62. }
  63. staticvoid err_doit(int errnoflag,int error,constchar*fmt, va_list ap)
  64. {
  65. char buf[MAXLINE];
  66. vsnprintf(buf, MAXLINE-1, fmt, ap);
  67. if(errnoflag)
  68. {
  69. snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1,": %s",
  70. strerror(error));
  71. }
  72. strcat(buf," ");
  73. fflush(stdout);/* in case stdout and stderr are the same */
  74. fputs(buf, stderr);
  75. fflush(NULL);/* flushes all stdio output streams */
  76. }
代码2. error.h的实现

静态库

    静态库都是以.a作为后缀,表示Archive
    例如: libmy.a   (my就是库名)

创建静态库

编译

gcc -c -static a.c b.c ...
    1) -static可选,可阻止gcc使用共享库 
        不使用共享库会使可执行文件变大,但会减少运行时间开销
    2) 写头文件(里面是那些函数的声明)
        源文件可以是多个或一个,里面是想要放到库中的函数的定义

打包

ar r libxxx.a a.o b.o ...
    ar[选项] 归档文件名  目标文件列表
    -r   将指定文件插入文档,如果存在则更新
    示例:  ar r libxxx.a  *.o
    -t   显示目标文件列表
    示例:  ar t libxxx.a 

使用静态库

    写调用源程序: main.c

第一种方式

gcc libxxx.a  main.c(或者main.o) -o main

第二种方式

    如果没有配置LIBRARY_PATH的环境变量,可以采用如下方式编译:
gcc  -lxxx(静态库名) -LXXX(静态库所在的路径) main.c -o main
    或者-l和xxx空一个空格
gcc  -l xxx -L XXX main.c -o main
    或者加-static选项
gcc -static -lxxx -LXXX main.c -o main
    其中-static表示如果同时存在同名的动态库和静态库,使用静态库(默认使用动态库)
示例:
gcc main.c -lerror -Llib

第三种方式

    如果libxxx.a在LIBRARY_PATH的指定目录中,还可以采用如下方式编译
gcc -lxxx main.c -o main
    配置环境变量LIBRARY_PATH
    export LIBRARY_PATH=库文件所在的路径

第三方静态库示例

sqrt函数

    库: libm.a (/usr/lib/libm.a)
    头文件: math.h (/usr/include/math.h)

静态库的优缺点

    运行时不再依赖静态库,代码已经嵌入到可执行文件中
    升级时需要重新编译链接
 

动态库

    又叫共享对象库(shared object library,简称共享库)

 

 
原文地址:https://www.cnblogs.com/fireway/p/6059207.html