linux静态链接库与动态链接库的区别及动态库的创建(转)

2023-10-29

linux静态链接库与动态链接库的区别及动态库的创建(转)

一、引言

通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象 文件(object file)与牵涉到的函数库(library)被链接合成一个可执行 文件(executable file)。 程序运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常 文件名为“libxxx.a”的形式。

其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是如雷贯耳的动态链接库(dynamic link library)技术。

二、动态链接库的特点与优势

首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

1. 可以实现进程之间的资源共享。

什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作 系统首先会查看所有正在运行的程序,看在 内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了 系统内存资源。C的标准库就是动态链接库,也就是说 系统中所有运行的程序共享着同一个C标准库的代码段。

2. 将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的 软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的 软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。

三、动态链接库的创建

由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库 函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须实用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器, 这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position Independent Code (PIC))。

对gcc编译器,只需添加上 -fPIC 标签,如:

gcc -fPIC -c file1.c
gcc -fPIC -c file2.c
gcc -shared libxxx.so file1.o file2.o

注意到最后一行,-shared 标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar  命令。也注意到,动态链接库的名字形式为 “libxxx.so” 后缀名为 “.so”

四、动态链接库的使用

使用动态链接库,首先需要在编译期间让编译器检查一些语法与定义。

这与静态库的实用基本一样,用的是 -Lpath 和 -lxxx 标签。如:

gcc file1.o file2.o -Lpath -lxxx -o program.exe

编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。

在程序运行期间,也需要告诉系统去哪里找你的动态链接库文件。在UNIX下是通过定义名为 LD_LIBRARY_PATH 的环境变量来实现的。只需将path赋值给此变量即可。csh 命令为:

setenv LD_LIBRARY_PATH your/full/path/to/dll

一切安排妥当后,你可以用 ldd 命令检查是否连接正常。

ldd program.exe


动态链接库*.so的编译与使用- -


动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。
1、动态库的编译

下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

so_test.h:

#include 
#include 

void test_a();
void test_b();
void test_c();


test_a.c:

#include "so_test.h"
void test_a()
{
printf("this is in test_a...\n");
}


test_b.c:
#include "so_test.h"
void test_b()
{
printf("this is in test_b...\n");
}

test_a.c:

#include "so_test.h"
void test_c()
{
printf("this is in test_c...\n");
}

将这几个文件编译成一个动态库:libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

2、动态库的链接

在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。

test.c:

#include "so_test.h"
int main()
{
test_a();
test_b();
test_c();
return 0;

}

l 将test.c与动态库libtest.so链接生成执行文件test:

$ gcc test.c -L. -ltest -o test

l 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了

$ ldd test

l 执行test,可以看到它是如何调用动态库中的函数的。
3、编译参数解析
最主要的是GCC命令行的一个选项:
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

l -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

l -L.:表示要连接的库在当前目录中

l -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

l LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

l 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
4、注意

调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux静态链接库与动态链接库的区别及动态库的创建(转) 的相关文章

  • Arduino多串口通信分离字符串最简单有效的方法

    本方法简单明了 经过本人的实际运行测试 用一个字形容perfect 串口1接收字符串格式为435 25 25 分号是分隔符 一个整型 一个浮点型 这两个数据是UNO上的传感器采集的数据 是变量 通过软件串口发送给上位机 这里是上位机的代码
  • 【C】ringbuffer的C语言实现

    最近在学习Android 下的Bluedroid时 看到在Bluedroid中实现了ringbuffer这一数据结构 比较简洁 所以独立出来进行分享 Bluedorid官方源码路径 本文分享的ringbuffer例子源码路径 什么是ring
  • zlib库各历史版本下载网址

    https zlib net fossils
  • C语言大数相乘的问题

    给你两个整数 请你计算A B 输入 数据的第一行是整数T 1 T 20 代表测试数据的组数 接着有T组数据 每组数据只有一行 包括两个非负整数A和B 但A和B非常大 Redraiment能保证这些数用long来保存一定会溢出 但A和B的位数
  • 判断单链表是否有环

    bool FixRing Node pHead Node pSlow pHead Node pFast pHead while pFast pFast gt next 如果存在环 不存在p next NULL的情况 pSlow pSlow
  • linux静态链接库与动态链接库的区别及动态库的创建(转)

    linux静态链接库与动态链接库的区别及动态库的创建 转 一 引言 通常情况下 对函数库的链接是放在编译时期 compile time 完成的 所有相关的对象 文件 object file 与牵涉到的函数库 library 被链接合成一个可
  • C++学习笔记一(重载、类)

    C 1 函数重载 2 类 2 1 类的方法和属性 2 2 类的方法的定义 2 3 构造器和析构器 2 4 类的实例化 2 5 基类与子类 2 6 类的public protected private继承 2 7 类的方法的重载 2 8 子类
  • C语言之结构体(Struct)

    Struct 结构体的两种定义方法 方法1 方法2 结构体的成员的初始化与访问 应用举例 结构体的两种定义方法 方法1 定义一个结构体 struct Name int temp1 float temp2 1 1 定义一个结构体变量 stru
  • MFC中传递消息的方法

    通过自定义消息实现进程间通信的方法 消息分为两种 即系统消息和用户 程序设计者 自定义消息 系统消息定义从0到0x3FF 可以使用0x400到0x7FFF定义自己的消息 Windows把0x400定义为WM USER 如果想定义自己的一个消
  • CTP:报单错误:不允许重复报单(原因及解决方案)

    CTP 报单错误 不允许重复报单 原因及解决方案 使用QT5 10 上期的CTP平台开发了一整套程序化交易系统 开发的过程中遇到了各种各样的问题 其中关于CTP接口的开发就遇到了很多坑 甚至很多坑是经过了一段时间的实盘测试才能被发现 本文所
  • JetBrains设置inline hint的背景色、前景色

    如题 修改IDE的hint前景色和背景色 修改后结果
  • C语言指针、字符串以及字符的异同

    文章目录 介绍 小实验1 小实验2 在单片机中的应用 介绍 指针 是存放某种特定变量的特定地址 字符 单引号内的字符 占八位 字符串 多个字符加一个结束符 0 组成 但其本质是一个指向第一个字符的指针 小实验1 任务 判断 hello wo
  • Windows中.exe程序的启动过程和C/C++运行时库<转载>

    很是受益 Windows中 exe程序的启动过程和C C 运行时库 lt 转载 gt Windows系统中 exe后缀的文件一般可以双击运行 编程时 编译出来的最终结果一般也表现为一个exe程序和其他的为程序执行提供支持的dll 我们双击一
  • feof()和EOF的用法—— C中文件结尾的判断

    昨天突然被一位朋友问到了关于文件结尾的程序问题 在用feof 判断文件时 复制会多产生一个字符 这个问题在大一的时候 老师上课就强调过 但那时只是模糊的记得个大概 记得这个函数如果用的不对就是会出现问题 解决是要先读一下 然后再判断 具体的
  • 解读 Q_D, Q_Q 指针

    见 qglog h文件定义 define Q D Class Class Private const d d func define Q Q Class Class const q q func d指针是在主类中使用的 来获取私有子类成员指
  • IAR编译项目时报以下错误

    根本原因是因为你宏定义不符合规范
  • C++:派生类的默认构造函数和拷贝构造函数调用基类构造函数的机制(含程序验证)

    1 如果基类定义了不带参数的默认构造函数 则编译器为派生类自动生成的默认构造函数会调用基类的默认构造函数 2 如果基类定义了拷贝构造函数 则编译器为派生类自动生成的拷贝构造函数同样会调用基类的拷贝构造函数 3 如果基类定义了带参数的构造函数
  • 前置++与后置++区别 以及效率

    之前在杭州实习面试中科视拓时候面试官问道 前置 与后置 区别 以及效率 打破对C 的认识 后来 寒假回来看书后才恍然大悟 前置 和后置 的区别 C专家编程 中有如下描述 P276 人民邮电出版社 a表示取a的地址 增加它的内容 然后把值放在
  • C语言之基本数据类型

    在学习C语言的时候 我们可能首先面对的就是C语言中基本的数据类型 下面来看一下C语言中一些基本的数据类型 基本数据类型 void 声明函数无返回值或无参数 声明无类型指针 显示丢弃运算结果 C89标准新增 char 字符型类型数据 属于整型
  • C++笔记--线程间共享数据

    当线程在访问共享数据的时候 必须制定一些规矩 用来限定线程可访问的数据位 还有 一个线程更新了共享数据 需要对其他线程进行通知 从易用性的角度 同一进程中的多个线程进行数据共享 错误的共享数据使用是产生并发bug的一个主要原因 当涉及到共享

随机推荐

  • C/C++ 获取当前时间(最全方法)

    文章目录 一 获取当前时间 1 使用C语言标准库 2 使用VS提供的ATL模板库 3 使用Win API 二 代码解析 1 time函数 2 localtime函数 3 tm结构体 4 localtime s函数 5 CTime类 6 Ge
  • Redis基本了解

    Redis 基于内存进 存储 持 key value 的存储形式 底层是 C 语 编写的 基于 key value 形式的数据字典 结构 常简单 没有数据表的概念 直接 键值对的形式完成数据的管理 Redis 持 5 种数据类型 字符串 列
  • RecyclerView详解 —— 自定义分割线

    RecyclerView作为ListView和GridView的升级版 Google并没有提供默认的分割线实现 不得不说这是一大遗憾 不过Google为我们提供了一个与之相关的抽象类 public static abstract class
  • 使用Element-Ui的el-select组件无法选中回显的问题

    最近在实习开发中使用了Element Ui的select组件 在选择上级科目下拉后出现了下拉无法回显的情况 但是在科目名称一填内容 上级科目马上就回显了的情况 经过排查也并不是下拉框绑定的值有问题 最后是使用了Vue 官方提供了 vm fo
  • 基于SSM+JSP的高校信息资源共享平台管理系统

    项目背景 21世纪的今天 随着社会的不断发展与进步 人们对于信息科学化的认识 已由低层次向高层次发展 由原来的感性认识向理性认识提高 管理工作的重要性已逐渐被人们所认识 科学化的管理 使信息存储达到准确 快速 完善 并能提高工作管理效率 促
  • Git的git fetch, git merge和git pull, git rebase操作

    Git push merge pull fetch rebase各自在什么场景下使用 基本上顺序是这样的 你修改好了代码 准备要提交到远程仓库 但是此时有可能其他人已经在此分支上已经进行了修改 那么该如何操作呢 这里我们就使用之前模拟多用户
  • 解决 Maven 本地仓库有jar包,还是要到远程仓库去取的问题

    删除maven本地仓库jar包目录下的 lastUpdated 和 repositories 文件 即可解决 使用cmd命令批量清除 cd d cd d maven local repository 首先要进入本地仓库目录 for r i
  • osg传递数组到shader,(以qedl为例)

    一 对float类型的数组 osg ref ptrosg FloatArray m dampingPixelDist 赋值 void ccBilateralFilter updateDampingTable m dampingPixelDi
  • python提示错误TypeError: write() argument must be str, not bytes

    还是在学习 Machine Learning in Action 中决策树一章中 在学习决策树存储过程中先是提示错误TypeError write argument must be str not bytes 看错误信息是说write 函数
  • halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划

    halcon与c 联合编程实现相机控制 图像平移缩放 日志记录 缺陷检测 路径规划 前言 本人近期在工作中遇到需要对某场景下利用海康相机进行图像缺陷检测与对应路径规划 通过对海康相机示例代码进行吸收与借鉴 最终实现了对海康相机的控制 并增加
  • 【c语言】新手学习了switch后的思考总结

    今天初学switch 有了一下四方面的思考 其一 switch是一种语句 这是否意味它需要在某函数内使用 由于初学我的表达不一定准确 即不能独立出来 其二 switch的定位为在多分支的情况下的一种优于 ifelse 的语句 但它的优点在哪
  • css三列布局--两边固定中间自适应和中间固定两边自适应

    三列布局 本篇讲三列布局 面试常考题 自己总结的 如有什么问题 欢迎指出 我会用红色标注出主要作用部分 都是最精简的写法 没有多余的修饰 布局方式一 两边固定中间自适应 1 flex布局 思路 将父元素box设为display flex 可
  • 如果只能推荐3本关于python的书,你会推荐哪3本?

    如果只能推荐3本Python书的话 我推荐这3本 第一本 Python编程快速上手 让繁琐工作自动化 第2版 豆瓣评分8 9 本书是一本面向初学者的Python编程实用指南 本书不仅介绍了Python语言的基础知识 而且通过案例实践教读者如
  • 【QT】Halcon与VS的联合编程2

    1 Halcon代码的导出 导出为C 语言 进行机器视觉应用 在halcon界面的菜单栏项上选择 文件 导出 界面如下 导出之后 在上述导出文件的路径下 你就可以看到程序了 此时这个程序就和halcon没有关系了 就是独立的cpp文件了 2
  • Web3社交基础设施SBT

    今年年初 V神发表了一篇文章并提出soulbound token SBT 概念 5月份 又联合撰写了一篇 去中心化社会 找寻 Web3 的灵魂 让 去中心化社会 和 SBT 概念在大熊市又爆火一波 SBT到底是什么 有什么价值 在概念到应用
  • windows批处理命令总结(超详细滴)

    总结自 https baike baidu com item E6 89 B9 E5 A4 84 E7 90 86 1448600 fr aladdin 文件夹管理 cd 显示当前目录名或改变当前目录 md 创建目录 rd 删除一个目录 d
  • 成功解决Win10连接上wifi但是却显示“无Internet,安全”

    成功解决Win10连接上wifi但是却显示 无Internet 安全 目录 解决问题 解决方法 解决问题 解决Win10连接上wifi但是却显示 无Internet 安全 解决方法 先将wlan先禁用 然后重新启用wlan即可
  • 文心一言和讯飞星火全面对比测试:(五)编程能力

    相关文章 实战 用ChatGPT处理word表格数据 直接采用ChatGPt和利用ChatGPT编写python脚本两种方法 文心一言 vs ChatGPT 结果没有你想向中的那么不堪 文心一言和讯飞星火全面对比测试 一 语言理解能力 文心
  • hbase中的HFile文件格式详解

    1 HFile详解 HFile文件分为以下六大部分 序号 名称 描述 1 数据块 由多个block 块 组成 每个块的格式为 块头 key长 value长 key value 2 元数据块 元数据是key value类型的值 但元数据快只保
  • linux静态链接库与动态链接库的区别及动态库的创建(转)

    linux静态链接库与动态链接库的区别及动态库的创建 转 一 引言 通常情况下 对函数库的链接是放在编译时期 compile time 完成的 所有相关的对象 文件 object file 与牵涉到的函数库 library 被链接合成一个可