• linux动静态库


    linux动静态库

    一、库的概念

    函数:某些功能代码的封装,可能通过将函数声明放置头文件当中,给其它文件进行调用,那么封装的函数可见(可以使用代码实现的过程),称为开源。封装的函数不可见(将代码实现的过程进行封装动静态库),称为闭源(不开源)。

    linux下有动静态库

    linux以.a结尾的是静态库,以.so结尾的为动态库; linux下默认的库路径/lib

    静态库:在编译时以函数叠加的方式增加到代码中,使用运行,可脱离库运行。使用静态库生成的可以文件相对较大,内存开销大,但是运行效率高。
    动态库:在编译时以链接的方式增加到代码中,当需要库函数时,才调用,使用动态库生成的可以文件相对较小,内存开销小,但是运行效率略低。

    二、 静态库的创建与使用

    使用ar工具创建静态库的时候需要两个参数:
    参数c:创建一个库,不管库是否存在,都将创建。
    参数r:在库中插入模块 (替换)。默认新的成员添加在库的结尾处,如果模块名已经在库中存在,则替换同名的模块。

    (1)在某个目录下编写三个.c(main.c add.c sub.c)文件及两个.h(add.h sub.h)文件,文件参与project。这个工程必须是编译通过才能制作库。
    main.c

    /*main.c*/
    #include 
    #include "sub.h"
    #include "add.h"
    
    
    int main(void)
    {
        int num, a, b;
    
        printf("请输入两个正整数:");
        scanf("%d%d", &a, &b);
    
        num = add(a, b);
        printf("两数之和:%d\n", num);
    
        num = sub(a, b);
        printf("两数之差:%d\n", num);
    
        return 0;
    }
    
    /*add.c*/
    #include "add.h"
    
    int add(int a, int b)
    {
        int num;
    
        num = a+b;
    
        return num;
    }
    
    /*sub.c*/
    #include "sub.h"
    
    int sub(int a, int b)
    {
        int num;
    
        num = a-b;
    
        return num;
    }
    
    /*sub.h*/
    #ifndef __SUB_H
    #define __SUB_H
    
    #include 
    
    int sub(int a, int b);
    
    
    
    #endif
    
    /*add.h*/
    
    #ifndef __ADD_H
    #define __ADD_H
    
    #include 
    
    int add(int a, int b);
    
    
    #endif
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    gec@ubuntu:~/Desktop/project$ gcc *.c -o main
    
    • 1

    或者

    gec@ubuntu:~/Desktop/project$ gcc main.c add.c sub.c -o main
    
    • 1

    (2)将需要封装.c文件生成.o文件

    gec@ubuntu:~/Desktop/project$ gcc -c add.c sub.c
    
    • 1

    (3).o文件生成.a(静态库文件), ar:生成静态库命令
    ar -rc xxx.a xxx.o xxx.o

    gec@ubuntu:~/Desktop/project$ ar -rc libmylib.a add.o sub.o
    
    • 1

    静态库命名:lib+库名(自定义)+.a 比如:libmylib.a

    (4)运用

    gec@ubuntu:~/Desktop/project$ gcc main.c -o main libmylib.a 
    gec@ubuntu:~/Desktop/project$ ./main
    
    请输入两个正整数:85 47
    两数之和:132
    两数之差:38
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    假设静态库在某个路径(/home/gec/libmylib.a ),编译方法:

    gec@ubuntu:~/Desktop/project$ gcc main.c -o main /home/gec/libmylib.a 
    
    • 1

    三、 动态库的创建与使用

    (1)在某个目录下编写三个.c(main.c add.c sub.c)文件及两个.h(add.h sub.h)文件,文件参考project里面代码。这个工程必须是编译通过才能制作库。

    
    
    • 1

    gec@ubuntu:~/Desktop/project$ gcc *.c -o main

    或者
    gec@ubuntu:~/Desktop/project$ gcc main.c add.c sub.c -o main

    
    
    • 1

    (2)将.c文件生成.so文件

    gec@ubuntu:~/Desktop/project$:gcc -fpic -shared xxx.c xxx.c -o libxxx.so
    
    • 1

    -fpic:表示编译为独立的代码块
    -shared:指定生成动态库
    libxxx.so:库名

    动态库命名::lib+库名(自定义)+.so+(版本号)

    例如:

    gec@ubuntu:~/Desktop/project$ gcc -fpic -shared sub.c add.c -o libmylib.so
    
    • 1

    (2)使用动态库进行编译(直接编译)

    gec@ubuntu:~/Desktop/project$ gcc main.c -o main libmylib.so 
    
    • 1

    或者

    gec@ubuntu:~/Desktop/project$ gcc main.c -o main ./libmylib.so (./表示当前路径)
    
    • 1

    或者

    gec@ubuntu:~/Desktop/project$ gcc main.c -o main /home/gec/libmylib.so 
    
    • 1

    (3)使用动态库进行编译(间接编译)
    假设动态库文件在:/home/gec目录下

    gec@ubuntu:~/Desktop/project$ gcc main.c -o main -L /home/gec/ -lmylib
    
    • 1

    gcc main.c -o main -L /home/gec/ -lmylib
    -L :指定库的路径标志
    /home/gec/ :库所在的路径
    -l :链接库标志
    mylib :库名

    假设头文件(/home/gec/include)与main.c不同的路径,编译方法:

    gcc main.c -o main -L /home/gec/ -lmylib -I /home/gec/include/
    
    • 1

    说明
    -I :指定头文件的路径标志
    /home/gec/include/:关文件路径

    或者将库存文件放置在系统默认的库路径下
    /lib 或者/usr/lib

    gec@ubuntu:~/Desktop/project$ sudo cp /home/gec/libmylib.so /usr/lib
    gec@ubuntu:~/Desktop/project$ gcc main.c -o main -lmylib
    
    • 1
    • 2

    使用动态库编译的程序运行方法
    **方法1:**将动态库放置到系统默认的库路径中
    /lib

    gec@ubuntu:~/Desktop/project$:sudo cp libmylib.so /lib
    
    gec@ubuntu:~/Desktop/project$: sudo cp libmylib.so /lib
    gec@ubuntu:~/Desktop/project$: ./main
    请输入两个正整数:45 25
    两数之和:70
    两数之差:20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    **方法2:**将动态库放置在任何位置,在系统的启动文件中添加环境变量即可,然后环境变量生效。

    gec@ubuntu:~/Desktop/project$: gedit  ~/.bashrc 
    
    在文件最后一行添加
    export LD_LIBRARY_PATH=/home/gec:$LD_LIBRARY_PATH
    
    • 1
    • 2
    • 3
    • 4

    执行下面命令,使环境变量生效

    gec@ubuntu:~/Desktop/project$: source ~/.bashrc 
    
    • 1

    如果上面命令不生效,关闭终端重启终端即可。

    gec@ubuntu:~/Desktop/project$ ./main
    请输入两个正整数:45 25
    两数之和:70
    两数之差:20
    
    • 1
    • 2
    • 3
    • 4

    这里是基于linux下的x86平台的库制作及运行,如果是运行的平台是arm,将对应的工具链换成对应的:arm-linux-gcc即可,本人已经测试过,可用。

  • 相关阅读:
    马拉车算法
    About 9.25 This Week
    隧道工程资质怎么办理,办理隧道工程三级资质有什么要求
    2024黑马AI+若依框架项目开发 个人心得、踩坑和bug记录 全网最快最全 基础功能认识篇
    代码随想录——接雨水(双指针&动态规划&单调栈)
    CesiumJS【Basic】- #006 浏览器控制台查看位置角度
    来自北大算法课的Leetcode题解:847. 访问所有节点的最短路径
    SQL如何从数据库中查找数据是否存在
    .locked勒索病毒的最新威胁:如何恢复您的数据?
    StyleGAN 生成 AI 虚拟人脸,再也不怕侵犯肖像权
  • 原文地址:https://blog.csdn.net/wwwqqq2014/article/details/126198612