linux中动态库和静态库

静态库

可重定位目标文件以一种特定的方式打包成一个单独的文件,并且在链接生成可执行文件时,从这个单独的文件中“拷贝”它自己需要的内容到最终的可执行文件中。这个单独的文件,称为静态库。linux中通常以.a(archive)为后缀

  • 生成:
ar rcs + 静态库文件的名字 + 目标文件列表
  • 使用:
gcc -c main.c
gcc -static -o main main.o -lm // 如果要链接libxxx.a,使用-lxxx即可)

-lm : 使用用到系统中的静态库libm.a

必须把 -lm放在main.o的后面。

lm放在main.o的前面,发生错误:

main.o: In function `main':
main.c:(.text+0x2a): undefined reference to `exp'
collect2: error: ld returned 1 exit status
必须把 -lm放在main.o的后面的原因
  • 放在最后时解析过程如下

    • 链接器从左往右扫描可重定位目标文件和静态库
    • 扫描main.o时,发现一个未解析的符号exp,记住这个未解析的符号
    • 扫描libm.a,找到了前面未解析的符号,因此提取相关代码
    • 最终没有任何未解析的符号,编译链接完成
  • 将-lm放到main.o 前面

    • 链接器从左往右扫描可重定位目标文件和静态库
    • 扫描libm.a,由于前面没有任何未解析的符号,因此不会提取任何代码
    • 扫描main.o,发现未解析的符号exp
    • 扫描结束,还有一个未解析的符号,因此编译链接报错

在这里插入图片描述

objdump  -d  main

使用反汇编查看 :
_exp函数也在main二进制文件中,函数调用的时候直接调用
在这里插入图片描述

动态库

动态库和静态库类似,但是它并不在链接时将需要的二进制代码都“拷贝”到可执行文件中,而是仅仅“拷贝”一些重定位和符号表信息,这些信息可以在程序运行时完成真正的链接过程。linux中通常以.so(shared object)作为后缀。

  • 生成
gcc -c -fpic -o main.o
gcc -shared -o main main.so
  • 使用:
gcc -o main main.c -lm  #默认使用的是动态链接

和静态库一样-lm 必须放到 main.c 后面;

文件大小明显比使用静态库小
在这里插入图片描述
动态库链接通过plt和got实现,通过_dl_runtime_resolve_xsave查找动态库中的函数
在这里插入图片描述

用到的实例代码:

#include<stdio.h>
#include<math.h>
int main(int argc,char *argv[])
{
    printf("hello 编程珠玑\n");
    int b = 2;
    double a = exp(b);
    printf("%lf\n",a);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值