编写简单的add/sub/mul/div函数,并打包成动/静态库,并分别使用。

动态库和静态库

首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。
什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件。另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间。
上面提到库在使用的时候需要 Link,Link 的方式有两种,静态和动态,于是便产生了静态库和动态库。

静态库(.a):程序在编译链接的时候把库的代码链接到可执 行 文件中。程序运 行的时候将不再需要静态库 。
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使 用库的代码。
一个与动态库链接的可执 行 文件仅仅包含它 用到的函数 入 口地址的 一个表,而不是外部函数所在 目标 文件的整个机器码
在可执 行 文件开始运 行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中, 这个过程称为动态链接(dynamic linking)

我们首先就要写4份代码,add.h ,add.c,sub.c,sub.h

`=========add.h=========``
 1 #pragma once         
 2 int add(int a,int b);   
==========add.c========             
  1 #include "add.h"
  2 int add(int a,int b)
  {    
     return a+b; 
  }
===========sub.h========
 1 #pargma once
 2 int sub(int a,int b); 
===========sub.c=======
  2 #include "sub.h"                         
  3 int sub(int a,int b)                                            
  4 {                                                                 
  5     return a-b;                                                   
  6 }    
===========main.c========
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "add.h"
  4 #include "sub.h"
  5 
  6 int main(void){
  7     int a=20;
  8     int b=10;
  9     printf("add(%d,%d)=%d\n",a,b,add(a,b));
 10     printf("sub(%d,%d)=%d\n",a,b,sub(a,b));
 11 }
 12 

生成静态库

静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之所以叫做静态,是因为静态库在编译的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。
静态库的好处很明显,编译完成之后,库文件实际上就没有作用了。目标程序没有外部依赖,直接就可以运行。当然其缺点也很明显,就是会使用目标程序的体积增大。
我们首先需要链接.o文件,生成add.o和sub.o文件
这里写图片描述
接下来我们需要生成静态库,并查看静态库的目录列表信息
这里写图片描述

ar是归档工具
rc表示(replace and create)
t:列出静态库中的文件
v:verbose 详细信息

接下来我们进行编译链接
这里写图片描述

-L 指定文件路径
-l: 指定库名

Linux下的库一般都是以lib开头的,以.a或者.so结尾的,但是在实际中我们的库函数应该是不用加前缀和后缀的。
显然我们已经看到结果是正确的,我们
但是我们知道静态链接是将代码拷一份给我的程序。所以按理说此时如果没有该库文件,可执行文件也可以正常运行。
这里写图片描述
所以我们就可以这样认为:说明静态链接是将库里的代码拷一份给我的可执行文件,我们再来观察下文件的大小。可执行文件要比其他文件大得多。
这里写图片描述


生成动态库

动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来。
动态库的优点是,不需要拷贝到目标程序中,不会影响目标程序的体积,而且同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库)。同时,编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。动态库带来的问题主要是,动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境。如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行(Linux 下喜闻乐见的 lib not found 错误)。
首先我们需要的是生成一个动态库
这里写图片描述

  • shared:表示生成共享库格式
  • fPIC:产生位置无关码(position independent code)
  • 库名规则:libxxx.so
    接下来我们进行使用该动态库
    这里写图片描述
    我们发现加载动态库出现了错误,那么我将提供解决这个问题的办法。
    ①拷贝.so文件到系统共享库路径下,一般是/usr/lib
    这里写图片描述
    ②更改LD_LIBRARY_PATH
    这里写图片描述
    ③ldconfg配置/etc/ld.so.conf.d/,ldconfg更新
    再用ldd命令:记录应用程序所依赖的动态库。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值