• Linux静态库与动态库详解


    引言
    为了代码的复用性和模块化,我们常常使用一些库文件,在Windows操作系统下位.lib  .dll作为静态库和动态库的后缀名。
    
    在Linux下,静态链接库名字一般为libabcdef.a,其中abcdef为该lib的名称
                        动态链接库名字一般为libabcde.so.major.minor,abcde为该lib的名称,major是主版本号,minor是副版本号
    

    下面来分别介绍一下静态链接库和动态链接库

    静态库
    1. 生成静态库。(以.a为后缀名)
      编写如下程序:
    
    /////////////////////////////////////////////////////////////////////////////////////
    /* program1.   hello.h */
    
    #ifndef HELLO_H
    #define HELLO_H
    
    void hello(const char *name);
    
    #endif
    /////////////////////////////////////////////////////////////////////////////////////
    
    
    /////////////////////////////////////////////////////////////////////////////////////
    /* program2.   hello.c */
    #include <stdio.h>
    void hello(const char *name) {
        printf("hello, %s
    ", name);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    
    
    /////////////////////////////////////////////////////////////////////////////////////
    /* program3.   main.c */
    #include "hello.h"
    int main(char argc, char *argv[])
    {
        hello("world");
        return 0;
    }
    /////////////////////////////////////////////////////////////////////////////////////
    
    

    编译hello.c,生成一个可重定位的目标文件hello.o

    $gcc -c hello.c
    
    

    Linux环境下使用ar工具创建一个静态库,或者将目标文件加入到一个已经存在的静态库中。并使用方法如下:

    $ar rcs 静态库名 目标文件1 目标文件2...目标文件n
    

    该明亮表示将目标文件1~n加入到指定的静态库中。如果该静态库不存在,则创建静态库文件,并且将库文件的扩展名
    命名为.a,其中ar工具的参数rcs弃了至关重要的作用。这3个参数分别表示:把列表中的目标文件加入到静态库中(参数r);
    若指定的静态库不存在,则创建该库文件(参数c);最后更新静态库文件的索引,使之包含新加入的目标文件的文件内容(参数s).
    现在,我们需要使用刚生成的hello.o目标文件,创建一个静态库文件libmyhello.a,其执行命令如下:

    $ar rcs libmyhello.a hello.o
    

    静态库制作完毕以后,可以看到在当前目录下生成了libmyhello.a文件

    备注:在某些系统中还要为静态库生成一个内容表

    $ranlib libmyhello.a
    
    1. 使用静态链接库
      在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成可执行文件时,指明静态库的名字。
      gcc将会从静态库中将公用函数连接到目标文件中。
      备注:gcc会在静态库名前加上前缀lib, 然后追加扩展名.a得到的静态库文件名来查找静态库文件。因此,我们在写需要连接到库时,
      只写名字就可以。如libmyhello.a的库,只写-lmyhello
    $gcc main.c -L. -lmyhello
    

    可以看到编译通过,并在当前目录下生成a.out可执行文件,执行可执行文件,即可生成hello, world

    如果想在编译的时候修改可执行文件的名字,可以使用如下命令:

    $gcc main.c -L. -lmyhello -o x_main
    

    使用gcc的-l选项来指定静态库,或者使用-L参数来指定库文件的搜索路径。
    -l和-L之后都直接带参数而不跟空格。因此,这里“."作为静态库的搜索路径。

    注意:在使用gcc链接静态库的时候的,其参数的顺序。
    -l是链接器选项,一定要放在被编译的源文件的文件名称之后,也就是本例中的main.c文件之后。若放在文件名称之前,则会链接失败。
    gcc也支持使用-static选项对静态库进行链接。

    因为静态库是直接编译到可执行文件中,我们可以删除掉当前目录下的libmyhello.a文件,
    然后重新执行可执行文件,可以看到:程序的结果与之前一样,表明静态库文件已经成功链接到可执行文件中了。

    静态链接库的缺点:
    如果我们同时运行了许多程序,并且它们使用了同一个库函数,这样,在内存中会大量拷贝同一个库函数。这样就会浪费掉很多珍贵的内存和存储空间。
    使用动态链接库就可以避免这个问题。

    当静态库与动态库同名时,gcc命令默认将优先使用动态库。

    动态库(未验证)

    1.在程序中使用动态库
    (1)如果是标准C语言库我们可以不指定其库路径和库名称
    (2)如果静态库处于/lib或/usr/lib下
    $gcc -o test test.c /usr/lib/libm.a 或 $gcc -o test test.c -lm
    他们的效果相同。-lm意味着命名为libm.a或libm.so的文件(注意Linux下的库文件都要以lib开头)。

    参考:
    《Linux C程序设计大全》吴岳等编著
    https://wenku.baidu.com/view/7d8602b265ce050877321301.html
    http://general.blog.51cto.com/927298/269044

    转载本Blog文章请注明出处,否则,本作者保留追究其法律责任的权利。 本人转载别人或者copy别人的博客内容的部分,会尽量附上原文出处,仅供学习交流之用,如有侵权,联系立删。
  • 相关阅读:
    升级到Net6后SignalR组件输出大量的Trace诊断日志
    mysql 权限设置
    mysql处理json数据
    mysql展示列的详细信息并可导出excel
    JPA使用笔记
    令牌桶算法实现限流
    left join(二) 方木
    left join(一) 方木
    时间处理及interval函数运用 方木
    concat()函数 方木
  • 原文地址:https://www.cnblogs.com/drfxiaoliuzi/p/7717282.html
Copyright © 2020-2023  润新知