zoukankan      html  css  js  c++  java
  • 静态库和动态库

    静态库和动态库

    引言

        将多个目标文件打包到一起,形成一个文件,叫库
        库文件名字都是以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,简称共享库)

     

     
  • 相关阅读:
    人这一辈子
    理性不是逆来顺受
    旧瓶新酒:江城子
    HVAC专业相关网站
    韩寒:主子,奴才和狗
    百无一用是书生
    inove主题文章字体修改
    这个世界清净了:再见人人
    ActiveX控件开发(转)
    GIS大讲堂内所有讲座的索引(更新至2008年6月26日)(转)
  • 原文地址:https://www.cnblogs.com/fireway/p/6059207.html
Copyright © 2011-2022 走看看