Linux中动态库的用法及优缺点?怎样制作动态库和静态库?

一、什么是gcc

gcc的全称是GNU Compiler Collection,它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器(GNU C Compiler),现在除了c语言,还支持C++、java、Pascal等语言。gcc支持多种硬件平台.

在 Linux 系统中,你可能会看到多个版本的 GCC 工具链,包括 gcc, gcc-ar, gcc-nm, 和 gcc-ranlib,以及这些工具的特定版本后缀(如 -7)。这些工具的存在有几个原因:

  1. 多版本共存:不同的项目可能需要不同版本的 GCC 来编译,以确保最佳性能、兼容性或利用新的编译器特性。Linux 系统允许多个版本的 GCC 共存,这样用户可以根据需要选择适合的版本。

  2. 不同工具的特定用途

    • gcc:这是 GNU 编译器集合的主编译器,用于编译 C、C++、Objective-C、Fortran、Ada 和 Go 等语言的代码。
    • gcc-ar:这是一个用于创建、修改和提取归档文件(静态库)的程序。它是 ar 命令的一个包装器,可以在 LTO(链接时间优化)过程中更好地处理归档。
    • gcc-nm:这个工具显示符号信息,它是标准的 nm 命令的包装器,特别用于处理 GCC 编译器生成的对象文件中的符号。
    • gcc-ranlib:这是用于生成归档库索引的工具,它是标凈的 ranlib 命令的包装器,有助于链接器更快地查找库中的符号。
  3. 特定版本的工具链

    • 后缀(如 -7)表示这些工具属于 GCC 的特定版本。例如,gcc-7, gcc-ar-7, gcc-nm-7, 和 gcc-ranlib-7 都是 GCC 版本 7 的组成部分。这些特定版本的工具在系统上同时存在是为了支持在同一系统上同时进行多个版本的开发。
  4. 系统更新与兼容性:随着新版本的发布,新工具链可能引入了改进的优化、更好的语言支持或新的编译器特性。然而,一些旧项目可能还是需要使用旧版本的编译器来保证兼容性。

这种安排给了开发者灵活性,使他们能够为不同的项目选择最合适的工具和版本,同时也保持了向后兼容性。在处理具体的构建和维护任务时,开发者可以根据需要选择使用特定版本的工具。

二、gcc的编译过程

gcc编译程序主要经过四个过程:

  • 预处理(Pre-Processing)
  • 编译 (Compiling)
  • 汇编 (Assembling)
  • 链接 (Linking)

      预处理实际上是将头文件、宏进行展开。编译阶段,gcc调用不同语言的编译器,例如c语言调用编译器ccl。gcc实际上是个工具链,在编译程序的过程中调用不同的工具。汇编阶段,gcc调用汇编器进行汇编。链接过程会将程序所需要的目标文件进行链接成可执行文件。汇编器生成的是可重定位的目标文件,学过操作系统,我们知道,在源程序中地址是从0开始的,这是一个相对地址,而程序真正在内存中运行时的地址肯定不是从0开始的,而且在编写源代码的时候也不能知道程序的绝对地址,所以重定位能够将源代码的代码、变量等定位为内存具体地址。下面以一张图来表示这个过程,注意过程中文件的后缀变化,编译选项和这些后缀有关。

三、GCC常用选项

现在我们有源文件hello.c,下面是一些gcc的使用示例: 

gcc -E hello.c -o hello.i   对hello.c文件进行预处理,生成了hello.i 文件
gcc -S hello.i -o hello.s    对预处理文件进行编译,生成了汇编文件
gcc -c hello.s -o hello.o  对汇编文件进行编译,生成了目标文件
gcc hello.o -o hello 对目标文件进行链接,生成可执行文件
gcc hello.c -o hello 直接编译链接成可执行目标文件
gcc -c hello.c 或 gcc -c hello.c -o hello.o 编译生成可重定位目标文件

使用gcc时可以加上-Wall选项。下面这个例子如果不加上-Wall选项,编译器不会报出任何错误或警告,但是程序的结果却不是预期的:


//bad.c
#include<stdio.h>
int main()
{printf("the number is %f ",5);  //程序输出了the number is 0.000000,结果错误return 0;}

很明显这段代码printf打印时,5是整数不是浮点类型。

使用-Wall选项:

gcc -Wall bad.c -o bad

生成的二进制文件还是可执行的,但是不是我们需要的结果。

四、使用外部库

在使用C语言和其他语言进行程序设计的时候,我们需要头文件来提供对常数的定义和对系统及库函数调用的声明。库文件是一些预先编译好的函数集合,那些函数都是按照可重用原则编写的。它们通常由一组互相关联的可重用原则编写的,它们通常由一组互相关联的用来完成某项常见工作的函数构成。使用库的优点在于:

  • 模块化的开发
  • 可重用性
  • 可维护性

库又可以分为静态库与动态库:

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。静态库比较占用磁盘空间,而且程序不可以共享静态库。运行时也是比较占内存的,因为每个程序都包含了一份静态库。

  • 动态库(.so或.sa):程序在运行的时候才去链接共享库的代码,多个程序共享使用库的代码,这样就减少了程序的体积。

一般头文件或库文件的位置在:

  • /usr/include及其子目录底下的include文件夹
  • /usr/local/include及其子目录底下的include文件夹
  • /usr/lib
  • /usr/local/lib
  • /lib

五 、静态库和动态库的优缺点

1.在Window中

.dll结尾的文件为动态库

.lib结尾的文件静态库

库即为源代码的二进制文件

2.在linux中

.so结尾的文件为动态库

.a结尾的文件为静态库

3.静态库和动态库的不同点

  • 二者的不同点在于代码被载入的时刻不同。

  • 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

  • 共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

4.库文件是如何产生的在Linux下

静态库的后缀是.a,它的产生分两步

Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表

Step 2.ar命令将很多.o转换成.a,成文静态库

动态库的后缀是.so,它由gcc加特定参数编译产生。

例如:

$ gcc -fPIC -c *.c $ gcc -shared -Wl,-soname, libfoo.so.1 -olibfoo.so.1.0 *.

5.库文件是如何命名的,有没有什么规范

在linux下,库文件一般放在/usr/lib和/lib下,

静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称

动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号

6.如何知道一个可执行程序依赖的共享库

ldd /path/to/your/executable

可以看到ln命令依赖于libc库和ld-linux库

五、静态库的制作实列

1.头文件mylib.h —— 声明静态库所导出的函数

#ifndef  _mylib_H_     //如果没有定义此标识符,编码以下程序
#define  _mylib_H_    void welcome();void outstring (const char * str);
#endif

(2) 对应于头文件的源文件mylib.c —— 实现静态库所导出的函数

#include "mylib.h"
#include <stdio.h>
void welcome() {printf ("welcome to libmylib\n");
}
void outstring(const char * str) {if (str !=NULL)printf ("%s",str);
}

(3)编译mylib.c生成目标文件:

# gcc –o mylib.o –c mylib.c

注: -c是只编译而不生成可执行文件,-o指定文件名

(4)将目标文件加入到静态库中,静态库为libmylib.a

   #ar rcs libmylib.a mylib.o

参数说明:
/* r —在库中加入新成员文件,如果要加入的成员文件存在,则替换之默认情况下,新的成员文件增加在库的结尾处
/* c 创建一个库

在linux环境中, 使用ar命令创建静态库文件.如下是命令的选项:

          d -----从指定的静态库文件中删除文件

          m -----把文件移动到指定的静态库文件中

          p -----把静态库文件中指定的文件输出到标准输出

          q -----快速地把文件追加到静态库文件中

          r -----把文件插入到静态库文件中

          t -----显示静态库文件中文件的列表

          x -----从静态库文件中提取文件

      还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:

          a -----把新的目标文件(*.o)添加到静态库文件中现有文件之后

          b-----***************************************之前

          v -----使用详细模式

ar 命令的命令行格式如下:

      ar[-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...

参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件.

/* s 无论ar命令是否修改了库内容,都强制重新生成库符号表

 (5)将静态库拷贝到 linux 的库目录(/usr/lib或/lib)下

这里我自己创建了一个存我编译好的静态库

(6)使用test.c调用静态库

#include "mylib.h"
#include <stdio.h>
int  main(){printf ("create and use library:\n");welcome();  //静态库中的函数原型outstring("It’s successful\n");  //静态库中的函数原型
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1411029.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

地震学角度说明横波纵波哪个才是垂直于传播方向振动

上面两幅图片&#xff0c;第一个是横波&#xff0c;第二个是纵波。死记硬背过一段时间总会忘记哪个是哪个。现通过地震学对横波纵波的定义来说明&#xff0c;如何从图形一眼判断横波和纵波。 横波&#xff1a; 因为地震的发生是由于地球内部的板块运动造成的&#xff0c;所以…

数据分析必备:一步步教你如何用numpy改变数据处理(2)

1、NumPy 简单入门教程 NumPy是Python中的一个运算速度非常快的一个数学库&#xff0c;它非常重视数组。它允许你在Python中进行向量和矩阵计算&#xff0c;并且由于许多底层函数实际上是用C编写的&#xff0c;因此你可以体验在原生Python中永远无法体验到的速度。 NumPy绝对是…

【软件开发规范篇】JAVA后端开发异常处理规范

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

01 Activiti 7:步骤

01 Activiti 7&#xff1a;步骤 1. 整合Activiti2. 业务流程建模3. 部署业务流程4. 启动流程实例5. 查询待办任务6. 处理待办任务7. 结束流程 1. 整合Activiti 业务系统使用 Activiti 来对系统的业务流程进行自动化管理。为了方便业务系统访问&#xff08;操作&#xff09;Act…

C语言 循环语句 (3) for 循环语句

接下来 我们来看第三个 for语句 基本语句是 for关键字 然后小括号 括号中三个表达式 然后它对表达式2进行判断 如果表达式2条件成立 则走进循环体 执行完循环体 会回来执行表达式3 然后再返回来 继续对表达式2进行判断 如果表达式2 还是成立 这继续循环往复 直到表达式2的条件…

《Fundamentals of Power Electronics》——隔离型CUK转换器、

以下是隔离型CUK转换器的相关知识点&#xff1a; Cuk电路的隔离型版本获得方式不同。基础非隔离型Cuk电路如下图所示。 将上图中电容C1分成两个串联的电容C1a和C1b&#xff0c;得到结果如下图所示。 在两个电容之间插入一个变压器&#xff0c;得到如下图所示电路。 变压器极性…

可视化大屏应用场景:智慧安防,保驾护航

hello&#xff0c;我是大千UI工场&#xff0c;本篇分享智慧安防的大屏设计&#xff0c;关注我们&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;我们也可以接单。 实时监控与预警 可视化大屏可以将安防系统中的监控画面、报警信息、传感器数据等实时展示在大屏上…

Java毕业设计 基于SSM SpringBoot vue宠物领养平台

Java毕业设计 基于SSM SpringBoot vue宠物领养平台 SSM 宠物领养平台 功能介绍 首页 图片轮播 新闻信息 新闻类型 新闻详情 宠物百科 宠物百科类型 宠物百科详情 宠物 宠物类型 宠物详情 立即领养 留言 论坛 发布帖子 登录 个人中心 宠物收藏 宠物领养订单 后台管理 登录注…

ssm104园区停车管理系统+jsp

园区停车管理系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管…

链表面试题及其解析

1.返回倒数第k个节点 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 示例&#xff1a; 输入&#xff1a; 1->2->3->4->5 和 k 2 输出&#xff1a; 4 说明&#xff1a; 给定的 k 保证是有效的。 1.1快慢指针 即慢指针一次走一步…

关于Windows登录密码的思考题

1. windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0c;密文存在哪个文件下&#xff0c;该文件是否可以打开&#xff0c;并且查看到密文 在Windows系统中&#xff0c;密码通常以哈希值的形式存储在注册表中的SAM文件中。SAM文件位于C:\Windows\System32\config\S…

简化Transformer模型,以更少的参数实现更快的训练速度

在深度学习领域&#xff0c;Transformer模型因其卓越的性能而广受欢迎&#xff0c;但其复杂的架构也带来了训练时间长和参数数量多的挑战。ETH Zurich的研究人员Bobby He和Thomas Hofmann在最新研究中提出了一种简化的Transformer模型&#xff0c;通过移除一些非必要的组件&…

FP16、BF16、INT8、INT4精度模型加载所需显存以及硬件适配的分析

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统 系统功能 首页 图片轮播 宾馆信息 饮食美食 休闲娱乐 新闻资讯 论坛 留言板 登录注册 个人中心 后台管理 登录注册 个人中心 用户管理 客房登记管理 客房调整管理 休闲娱乐管理 类型信息管理 论坛管理 系统管理 新闻资讯…

文心一言 VS 讯飞星火 VS chatgpt (251)-- 算法导论18.2 4题

四、假设关键字 {1&#xff0c;2&#xff0c;…&#xff0c;n} 被插入一棵最小度数为 2 的空 B 树中&#xff0c;那么最终的B树有多少个结点&#xff1f;如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; B树&#xff08;B-tree&#xff09;是一种自平衡的树&…

2024年钉钉群直播回放如何永久保存

工具我已经打包好了&#xff0c;有需要的自己取一下 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 1.首先解压好我给大家准备好的压缩包 2.再把逍遥一仙下载器压缩包也解压一下 3.打开逍遥一仙下载器文件夹里面的M3U8…

2022蓝桥杯国赛

题目描述&#xff1a; 思路&#xff1a; 题主用了两个方法&#xff0c;一个是三维数组&#xff0c;1到2022个数可以当成编号&#xff0c;f[i][j][k]表示前i个数选了j个数总和为k&#xff0c;存在是否选择第i个数的问题&#xff0c;选择第i个数为f[i-1][j-1][k-i];没有选择第i个…

计算机网络实验——学习记录六(TCP协议流量控制分析)

1. nc -d 5 -lv 4499 > 10K.1 其中&#xff1a; &#xff08;1&#xff09;-d 5 表示建立连接之后&#xff0c;延迟5秒再读取数据&#xff1b; &#xff08;2&#xff09;> 10K.1 表示将输出重定向到文件10K.1中&#xff1b; 2. 零窗口通知报文 3. 窗口探测报文

Gitea 上传用户签名

在 Gitea 的用户管理部分&#xff0c;有一个 SSH 和 GPG 的选项。 单击这个选项&#xff0c;可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户&#xff0c;可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。 单击这个导出&#xff0c;…

Redis 实战3

系列文章目录 本文将从跳跃表的实现、整数集合来展开 Redis 实战 Ⅲ 系列文章目录跳跃表的实现跳跃表节点层 前进指针跨度 整数集合的实现升级升级的好处提升灵活性节约内存 降级整数集合 API总结 跳跃表的实现 Redis 的跳跃表由 redis.h/zskiplistNode 和 redis.h/zskiplist…