服务器之家:专注于服务器技术及软件下载分享
分类导航

Linux|Centos|Ubuntu|系统进程|Fedora|注册表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服务器之家 - 服务器系统 - Linux - Linux静态库与动态库实例详解

Linux静态库与动态库实例详解

2022-02-19 19:27JeemyJohn Linux

这篇文章主要介绍了 Linux静态库与动态库实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下

Linux静态库与动态库实例详解

1. Linux 下静态链接库编译与使用

首先编写如下代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// main.c
#include "test.h"
int main(){
  test();
  return 0; 
}
 
// test.h
#include<iostream>
using namespace std;
void test();
 
// test.c
#include "test.h"
void test(){
 cout<< "test!" <<endl;
}

然后编译:

1. gcc -c test.c //生成目标文件
2. ar crv libtest.a test.o //生成静态链接库libtest.a
3. g++ -o main main.c -ltest //编译main程序同时链接libtest.a静态库
4. ./main //运行main程序

2. Linux 下动态链接库编译与使用

代码与上述一致。

然后编译:

1. g++ -fPIC -shared -o libtest.so test.c //生成动态链接库libtest.so
2. g++ -o main main.c -ltest //调用动态链接库libtest.so
3. ./main //运行main程序

3. 链接时缺失了相关目标文件(.o)

代码与上述一致。

编译过程如下:

1. gcc -c test.c
2. gcc -c main.c
3. gcc -o main main.o

这时,你会发现,报错了:undefined reference to `test'.

这就是最典型的 undefined reference 错误,因为在链接时发现找不到某个函数的实现文件, 本例中test.o文件中包含了test()函数的实现,所以如果按下面这种方式链接就没事了。

?
1
1. gcc -o main main.o test.o
?
1
2
3
4
5
6
7
8
【扩展】:其实上面为了让大家更加清楚底层原因,我把编译链接分开了,下面这样编译
也会报undefined reference错,其实底层原因与上面是一样的。
 
gcc -o main main.c //缺少test()的实现文件
 
需要改成如下形式才能成功,将test()函数的实现文件一起编译。
 
gcc -o main main.c test.c //ok,没问题了

4. 链接时缺少相关的库文件(.a/.so)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
在此,只举个静态库的例子,假设源码与上述一致。
 
1. 把test.c编译成静态库:
  gcc -c test.c
  sr -rc test.a test.o
  gcc -c main.c
 
2. 生成可执行程序:
  gcc -o main -main.o
 
    此时同样出现 undefined reference to `test'报错。其根本原因也是找不到test()函数的实现文
  件,由于该test()函数的实现在test.a这个静态库中的,故在链接的时候需要在其后加入test.a这个
  库,链接命令修改为如下形式即可。
  1. gcc -o main main.c ./test.a

5. 多个库文件链接顺序问题

?
1
2
3
4
5
6
7
8
9
10
11
12
这种问题也非常的隐蔽,不仔细研究你可能会感到非常地莫名其妙。我们依然回到第3小节所讨论
的问题中,在最后,如果我们把链接的库的顺序换一下,看看会发生什么结果?
 
1. gcc -o main main.o func.a test.a
 
我们会得到如下的编译错误:
 
1. test.a(test.o): In function `test':
2. test.c:(.text+0x13): undefined reference to `func'
3. collect2: ld returned 1 exit status
因此,我们需要注意,在链接命令中给出所依赖的库时,需要注意库之间的依赖顺序,依赖其他库
的库一定要放到被依赖库的前面,这样才能真正避免undefined reference的错误,完成编译链接。

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

原文链接:http://blog.csdn.net/u013709270/article/details/53264141

延伸 · 阅读

精彩推荐
  • LinuxManjaro Linux 0.8.13发布下载 可将系统装入SD卡

    Manjaro Linux 0.8.13发布下载 可将系统装入SD卡

    今天,该发行版已经发布了0.8.13这个新版本,并且提供了两大流行的桌面环境,即XFCE 4.12和KDE Plasma 5.3.1。Manjaro 0.8.13最明显的改进在于“Thus”安装器,尤其...

    服务器之家3722019-09-29
  • LinuxLinux系统中清理文件和清理环境变量的方法

    Linux系统中清理文件和清理环境变量的方法

    这篇文章主要介绍了Linux系统中清理文件和清理环境变量的方法,清理文件是利用find命令而清理环境变量则是使用env命令,需要的朋友可以参考下...

    开源中文社区3992019-09-03
  • LinuxLinux 中断子系统:GIC 中断控制器

    Linux 中断子系统:GIC 中断控制器

    GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器,类似 Cortex-M 内核(STM32)中的 NVIC。目前 GIC 有 4 个版本:V1~V4,V1 是最老的版本,已经被废弃了。...

    嵌入式Linux系统开发4472021-12-10
  • Linux图文详解Linux服务器搭建JDK环境

    图文详解Linux服务器搭建JDK环境

    这篇文章主要以图文结合的方式详细介绍了Linux服务器搭建JDK环境的过程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    谙忆6152021-11-17
  • LinuxLinux 5.12 或将支持 Clang LTO

    Linux 5.12 或将支持 Clang LTO

    对于 GCC 编译器的替代者 Clang , Linux 或将在 2 月份 5.12 版本中支持其 LTO ( link-time optimizations ) 功能。 这些补丁由谷歌软件工程师 Sami Tolvanen 提交,目前被...

    开源中国11822021-01-14
  • Linuxlinux ls命令的20个实用范例

    linux ls命令的20个实用范例

    Linux中一个基本命令是ls。没有这个命令,我们会在浏览目录条目时会遇到困难。这个命令必须被每个学习Linux的人知道 ...

    linux命令大全5942019-11-22
  • Linux在SSH代理中实现秘密握手的方法

    在SSH代理中实现秘密握手的方法

    这篇文章主要介绍了在SSH代理中实现秘密握手的方法,文中的怪物即是指国内拦截用户正常访问网站的...需要的朋友可以参考下 ...

    服务器之家3862019-09-11
  • Linux理解 ARM64 内核中对 52 位虚拟地址的支持

    理解 ARM64 内核中对 52 位虚拟地址的支持

    从 Linux 5.4 内核开始, arm64 架构中的 52 位(大)虚拟地址(VA)和物理地址(PA)得到支持。尽管内核文档描述了这些特性和新的内核运行时对旧的 CPU(硬...

    Linux中国11812021-01-31