动态库

LINUX总结第13篇:LINUX下动态库及版本号控制

亡梦爱人 提交于 2020-02-29 16:32:54
前言 针对同一动态组件的不同版本链接和加载。 一、概念 DLL HELL字面意思是DLL"灾难",是由于com组件(动态库)升级引起的程序不能运行的情况。 原因 有三种可能的原因导致了DLL Hell的发生: 一是由使用旧版本的DLL替代原来一个新版本的DLL而引起的。这个原因最普遍,是Windows 9X用户通常遇到的DLL错误之一。 二是由新版DLL中的函数无意发生改变而引起。尽管在设计DLL时候应该向下兼容,然而要保证DLL完全向下兼容却是不能的。 三是由新版DLL的安装引入一个新的Bug。 二、linux下的解决方案——命名规范 Linux 上的Dll ,叫sharedlibrary。Linux 系统面临和Window一样的问题,如何控制动态库的多个版本问题。为解决这个问题,Linux 为解决这个问题,引入了一套命名机制,如果遵守这个机制来做,就可以避免这个问题。但是这只事一个约定,不是强制的。但是建议遵守这个约定,否则同样也会出现 Linux 版的Dll hell 问题。 Real Name 首先是共享库本身的文件名:共享库的命名必须如 libname.so.x.y.z最前面使用前缀”lib”,中间是库的名字和后缀”.so”,最后三个数字是版本号。x是主版本号(Major Version Number),y是次版本号(Minor Version Number)

[C] linux静态链接库与动态链接库详解

半城伤御伤魂 提交于 2020-02-29 16:25:11
一顺便说说了哦 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file).程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为"libxxx.a"的形式. 其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime).这就是如雷贯耳的动态链接库(dynamic link library)技术. 二动态链接库的特点与优势 首先让我们来看一下,把库函数推迟到程序运行时期载入的好处: 1.可以实现进程之间的资源共享。 什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段. 2.将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。 3

(转)Linux如何解决动态库的版本控制

纵饮孤独 提交于 2020-02-29 15:35:12
(换句话说,soname不是真实存在的文件,只是在此库中和将来调用此库的文件中保存的一个名字,在加载时去找这个名字,使用时创建一个软连接来指向真实文件,这样真实文件的版本号就可以升级了) Linux 系统,也同样面临和Window一样的问题,如何控制动态库的多个版本问题。Window之前没有处理好,为此专门有个名词来形容这个问题 “Dll hell”,其严重影响软件的升级和维护。 Dll hell 是指windows 上动态库新版本覆盖旧版本,但是却不兼容老版本。常常发生在程序升级之后,动态库更新,原有程序运行不起来;或者装新软件,但是已有的软件运行不起来。 同样Linux操作系统,也有同样的问题,那么它是怎么解决的呢? Linux 为解决这个问题,引入了一套机制,如果遵守这个机制来做,就可以避免这个问题。 但是这只事一个约定,不是强制的。但是建议遵守这个约定,否则同样也会出现 Linux 版的Dll hell 问题。 下面来介绍一个这个机制。 这个机制是通过文件名,来控制dll (shared library) 的版本。 Linux 上的Dll ,叫shared library,其有三个名字,分别有不同的目的。 第一个是共享库本身的文件名(real name),其通常包含版本号,常常是是这样: libmath.so.1.1.1234 。 lib是Linux 上的库的约定前缀

lib 和 dll 的区别、生成以及使用详解

倾然丶 夕夏残阳落幕 提交于 2020-02-28 21:16:50
【目录】 lib dll介绍 生成动态库 调用动态库 生成静态库 调用静态库 首先介绍一下静态库(静态链接库)、动态库(动态链接库)的概念,首先两者都是代码共享的方式。 静态库 : 在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的 可执行文件 中,这种库称为静态库,其特点是 可执行文件 中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库 中的指令都全部被直接包含在最终生成的 EXE 文件 中了。 在vs中新建生成静态库的工程,编译生成成功后,只产生一个.lib文件 动态库 :动态链接库 是一个包含可由多个 程序 同时使用的 代码 和数据的库,DLL不是 可执行文件 。 动态链接 提供了一种方法,使进程可以调用不属于其 可执行代码 的函数。函数的 可执行代码 位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分 开存储的函数。 在vs中新建生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件 那么上述静态库和动态库中的lib有什么区别呢? 静态库中的lib :该 LIB包含函数代码本身(即包括函数的索引,也包括实现),在编译时直接将代码加入程序当中 动态库中的lib :该 LIB包含了函数所在的DLL文件和文件中函数位置的信息(索引),函数实现代码由运行时加载在进程空间中的DLL提供 总之

Android Studio 基于cmake 引入so库

筅森魡賤 提交于 2020-02-28 09:38:05
1. 搭建环境 环境变量: sudo apt-get remove openjdk* export JAVA_HOME=/opt/java/jdk1.8.0_211 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export NDK=/opt/java/android-ndk-r13b export ANDROID_SDK=/opt/Sdk export PATH=.:${JAVA_HOME}/bin:$PATH:$NDK:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools export ANDROID_SDK=/opt/Sdk export PATH=.:${JAVA_HOME}/bin:$PATH:$NDK:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools export CC=/opt/java/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc echo $CC #编译arm 下执行gcc export

GCC编译

拜拜、爱过 提交于 2020-02-27 14:45:50
一、GCC编译选项解析 1. 常用的编译选项 命令格式: gcc [选项] [文件名]   -E:仅执行编译预处理;   -S:将C代码转换为汇编代码;   -c:仅执行编译操作,不进行连接操作;     -o:指定生成的输出文件。 2. gcc编译的四个阶段 1) 将hello.c预处理输出hello.i文件 gcc -E hello.c -o hello.i 2) 将预处理输出文件hello.i汇编成hello.s文件   gcc -S hello.i -o hello.s 3) 将汇编输出文件hello.s编译输出hello.o文件   gcc -c hello.s -o hello.o 4) 将编译输出文件hello.o链接成最终可执行文件hello gcc hello.o -o hello 或直接输入下面的代码,一步到位: gcc hello.c -o hello 当有多个文件需要一起编译时,可输入 gcc *.c -o hello 二、多模块、多个文件一起编译 1. 两种编译方式 1)一起编译 gcc test_a.c test_b.c -o test 2)分别编译各个源文件,之后对编译后输出的目标文件链接   gcc -c test_a.c //生成test_a.o   gcc -c test_b.c //生成test_b.o   gcc -o test_a.o

动态库

落花浮王杯 提交于 2020-02-26 19:21:03
总结一:动态库 前言   我们知道程序编译链接经常使用动态,同时我们可能还知道,动态库时程序运行时加载的。但是动态库到底有什么作用,如何生成、如何加载等,我们却很少关注。接下来,我给大家做一个简单的介绍。 1.1 动态库和静态库的区别 静态库特点(linux): 命名上是以 *.o 结尾 静态库在链接阶段直接就加入到可执行的文件中了,在执行过程中无需该静态库 相对于动态库生成的文件,使用静态库生成的文件连接生成的可执行文件较大 动态库的特点(linux) 命名上是以 *.so 目标文件在链接阶段只是指明链接的那个动态库,动态库与目标文件保持独立。在执行过程中需要该动态库 使用动态库生成的目标文件较小 对于工程中比较共通的源码文件,比如多个进程使用同一个模块的源码,我们最好将其制作成动态库,以节省系统空间。同时如果动态库出现bug,只需要重新生成一个动态库并将以前的替换即可。不需要重新编译其他模块。 1.2 内存中的动态库 在讲到动态库的装载时我们需要懂一定的背景知识,首先虚拟内存和物理内存,其次还有地址映射,这些知识就不在本文多加讲解,网上资料很多。我们动态库在整个内存空间是有一份,而每个进程都有自己的虚拟空间,虚拟空间会使用匿名映射(mmap使用MAP_PRIVATE方式进行映射),使自己的进程与动态库进行关联。本进程只会保留访问动态库时的一些数据。好了,打的方向就说这么多

GCC -fPIC选项

℡╲_俬逩灬. 提交于 2020-02-26 08:18:56
我已经阅读了 GCC的代码生成约定选项 ,但无法理解“生成与位置无关的代码(PIC)”的作用。 请举例说明一下这是什么意思。 #1楼 进一步添加...... 每个进程都有相同的虚拟地址空间(如果通过在linux OS中使用标志来停止虚拟地址的随机化)(更多详细信息 仅为我自己禁用并重新启用地址空间布局随机化 ) 因此,如果它的一个exe没有共享链接(假设情景),那么我们总是可以给同一个asm指令提供相同的虚拟地址而不会有任何伤害。 但是当我们想要将共享对象链接到exe时,我们不确定分配给共享对象的起始地址,因为它将取决于共享对象链接的顺序。那么说,asm指令里面.so将始终有不同的虚拟地址取决于其链接的进程。 因此,一个进程可以将.so的起始地址作为0x45678910放在其自己的虚拟空间中,同时其他进程可以给出起始地址0x12131415,如果它们不使用相对寻址,则.so根本不起作用。 所以他们总是必须使用相对寻址模式,因此使用fpic选项。 #2楼 对已经发布的答案的一个小补充:未编译为位置无关的目标文件是可重定位的; 它们包含重定位表条目。 这些条目允许加载程序(将程序加载到内存中的代码位)重写绝对地址,以调整虚拟地址空间中的实际加载地址。 操作系统将尝试与链接到同一共享对象库的所有程序共享加载到内存中的“共享对象库”的单个副本。 由于代码地址空间(与数据空间的部分不同

何时使用动态库和静态库

半世苍凉 提交于 2020-02-26 08:17:46
在C ++中创建类库时,可以选择动态( .dll , .so )和静态( .lib , .a )库。 它们之间有什么区别,何时适合使用哪种? #1楼 如果您的库将在多个可执行文件之间共享,那么使其动态化以减小可执行文件的大小通常是有意义的。 否则,一定要让它静止。 使用dll有几个缺点。 加载和卸载它还有额外的开销。 还有一个额外的依赖。 如果您更改dll以使其与您的执行不兼容,它们将停止工作。 另一方面,如果更改静态库,则使用旧版本的已编译可执行文件不会受到影响。 #2楼 静态库被编译到客户端。 在编译时使用.lib,并且库的内容成为使用可执行文件的一部分。 动态库在运行时加载,不会编译到客户端可执行文件中。 动态库更灵活,因为多个客户端可执行文件可以加载DLL并利用其功能。 这还可以将客户端代码的总体大小和可维护性降至最低。 #3楼 静态库会增加二进制代码的大小。 它们总是被加载,并且您编译的代码的任何版本都是将运行的代码的版本。 动态库分别存储和版本化。 如果 更新被认为与原始版本二进制兼容,则可能会加载一个与您的代码一起提供的原始动态库版本。 另外,动态库不一定要加载 - 它们通常在第一次调用时加载 - 并且可以在使用相同库的组件之间共享(多个数据加载,一个代码加载)。 大多数时候动态库被认为是更好的方法,但最初他们有一个主要的缺陷(谷歌DLL地狱)

静态库与动态库的创建与使用

泪湿孤枕 提交于 2020-02-25 08:06:25
静态库:Windows中为后缀为.lib的文件,Linux中为.a文件; 动态库:Windows中为后缀为.dll的文件,Linux中为.so文件; Windows中: 调用静态库:将静态库路径添加进来——依赖静态库(或者#pragma comment(lib,xx.lib))——包含头文件——,用户程序中则可直接调用静态库中的函数 调用动态库:分为1)静态调用,即隐式调用:将库路径和头文件路径添加进来——依赖静态库选项(或者#pragma comment(lib,xx.lib))——包含头文件——用户程序中则可直接调用动态库态库中的函数 (注意之所以成为隐式调用动态库,是因为它是根据生成动态库时同时产生的静态库.lib文件中的函数地址来调用动态库中的函数的) 2)动态调用:不需要任何操作,只需要直接使用loadlibray_getproaddress_freelibray api来手动直接调用动态库的API即可 来源: https://www.cnblogs.com/happyliuyi/p/5490229.html