linux动态库命名规则
说道“动态库版本兼容”,很多人头脑中首先蹦出的就是“Dll Hell”。啊,这曾经让人头疼的难题。时至今日,这个难题已经很好地解决了。
在进一步讨论之前来思考一个问题:Linux下为什么没有让人头痛的“DllHell”?
回答这个问题,非常easy,因为——Linux下根本没有dll!
哈哈,当然这只是个玩笑,接下来展开一下这个话题,很多有动态库的系统都会面临这个难题,但各自解决的思路却各不相同。
Dll hell是指windows 上动态库新版本覆盖旧版本,但是却不兼容老版本。常常发生在程序升级之后,动态库更新,原有程序运行不起来;或者装新软件,但是已有的软件运行不起来。
一、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),z是发布版本号(Release Version Number)。
主版本号(不兼容):重大升级,不同主版本的库之间的库是不兼容的。所以如果要保证向后兼容就不能删除旧的动态库的版本。
次版本号(向下兼容): 增量升级,增加一些新的接口但保留原有接口。高次版本号的库向后兼容低次版本号的库。
发布版本号(相互兼容):库的一些诸如错误修改、性能改进等,不添加新接口,也不更改接口。主版本号和此版本号相同的前提下,不同发布版本之间完全兼容。
SO-NAME
严格遵守上述规定,确实能避免动态库因为版本冲突的问题,但是读者可能有疑问:在程序加载或运行的时候,动态链接器是如何知道程序依赖哪些库,如何选择库的不同版本?
Solaris和Linux等采用SO-NAME( Shortfor shared object name )的命名机制来记录共享库的依赖关系。每个共享库都有一个对应的“SO-NAME”(共享库文件名去掉次版本号和发布版本号)。比如一个共享库名为libtest.so.3.8.2,那么它的SO-NAME就是libtest.so.3。
在Linux系统中,系统会为每个共享库所在的目录创建一个跟SO-NAME相同的并且指向它的软连接(Symbol Link)。这个软连接会指向目录中主版本号相同、次版本号和发布版本号最新的共享库。也就是说,比如目录中有两个共享库版本分别为:/lib/libtest.so.3.8.2和/lib/libtest.so.3.7.5,么软连接/lib/libtest.so.3指向/lib/libtest.so.3.8.2。
建立以SO-NAME为名字的软连接的目的是,使得所有依赖某个共享库的模块,在编译、链接和运行时,都使用共享库的SO-NAME,而不需要使用详细版本号。在编译生产ELF文件时候,如果文件A依赖于文件B,那么A的链接文件中的”.dynamic”段中会有DT_NEED类型的字段,字段的值就是B的SO-NAME。这样当动态链接器进行共享库依赖文件查找时,就会依据系统中各种共享库目录中的SO-NAME软连接自动定向到最新兼容版本的共享库。
★ readelf -d sharelibrary 可以查看so-name
★ Linux提供了一个工具——ldconfig,当系统中安装或更新一个共享库时,需要运行这个工具,它会遍历默认所有共享库目录,比如/lib, /usr/lib等,然后更新所有的软链接,使她们指向最新共享库。
Link Name
当我们在编译器里使用共享库的时候,如用GCC的“-l”参数链接共享库libtXXX.so.3.8.1,只需要在编译器命令行指定 -l XXX 即可,省略了前缀和版本信息。编译器会根据当前环境,在系统中的相关路径(往往由-L参数指定)查找最新版本的XXX库。这个XXX就是共享库的“链接名”。不同类型的库可能有相同的链接名,比如C语言运行库有静态版本(libc.a)也动态版本(libc.so.x.y.z)的区别,如果在链接时使用参数”-lc”,那么连接器就会根据输出文件的情况(动态/静态)来选择合适版本的库。eg. ld使用“-static”参数时吗,”-lc”会查找libc.a;如果使用“-Bdynamic”(默认),会查找最新版本的libc.so.x.y.z。
更详细可以参见
http://www.linuxidc.com/Linux/2012-04/59071.htm
.Net下的解决方案——Manifest文件
.Net框架中,一个程序集(Assembly)有两种类型:应用程序程序集(.exe)与库程序集(DLL动态链接库)。一个程序集包括一个或个文件,所以需要一个清单文件(Manifest文件)来描述程序集。Manifest文件描述了程序集的名字,版本号以及程序集的各种资源,同时也描述了该程序集的运行所依赖的资源,包括DLL以及其他资源文件等。Manifest是一个XML文件。每个DLL有自己的Manifest。对于应用程序而言,manifest文件可以和可执行文件在同一目录,也可以作为一个资源嵌入到可执行文件内部(Embed Manifest)。
XP以前的windows版本,在执行可执行文件是不会考虑manifest文件的。它会直接到system32目录下查找可执行文件锁依赖的DLL。在这种情况下,manifest是多余的。XP之后的操作系统,在执行可执行文件时则会首先读取程序集的manifest文件,获得该可执行文件需要调用的DLL列表,操作系统再根据DLL的manifest文件去寻找对应的DLL调用。
Windows的解决方案——COM组件
采用标准COM组件,有很多好处:面向接口和对象编程语言无关性,采用二进制标准,可以实现跨语言调用版本升级方便,增加新接口,组件升级后老客户程序不用重新编译位置透明,客户程序不用关心组件的位置重用方便,通过包容和聚合可以快速重用已有组件我们可以看到标准COM组件非常强大,但是很多时候我们并不需要标准COM组件的所有特性,比如我们不希望引入注册表,也不希望引入COM运行库,我们希望我们的程序是完全“绿色”的。这时我们就会采用“COM思想架构“开发非标准的COM组件。
相关文章:

如何在同一系统里同时启动多个Tomcat
需要在同一系统里启动多个tomcat,应该怎么处理? tomcat是个服务程序,需要占用几个通讯端口,所以默认情况是不能启动多个tomcat,如果要启动多个tomcat,需要修改配置文件,通过在配置文件设置不同的通讯端口就可以做到.文件 %TOMCAT_HOME%/conf…

【ACM】Uva 455
【题目】:如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串以k为周期。输入一个长度不超过80的字符串,输出其最小正周期。 注意以下几点: 1、它的最小正周期一定可以被它的长度整除。 2第一个大循环下 i 可以等于…

前端自动化构建工具webpack (二)之css和插件加载总结
1. webpack只识别js文件,其他文件都需要转换成js文件。所有文件都是模块; 2. css解析 css需要css-loader ---》style-loader -----》less-loader less文件还需要less-loader (注意书写顺序) 3. plugins:他是一个数组&#…

使用command对象操作数据库
1.Command对象查询数据库 protected void Button1_Click(object sender, EventArgs e){//读取web.config节点配置string strcon ConfigurationManager.ConnectionStrings["testjm"].ConnectionString;//实例化sqlConnection对象SqlConnection con new SqlConnectio…

浅析C语言之uint8_t / uint16_t / uint32_t /uint64_t
一、C语言基本数据类型回顾 在C语言中有6种基本数据类型:short、int、long、float、double、char 1、数值类型 1)整型:short、int、long 2)浮点型:float、double 2、字符类型:char 二、typedef回顾 …

【ACM】UVa 489 刽子手游戏(自顶向下)
【题目】 Hangman Judge是一个猜英文单字的小游戏(在电子字典中常会看到),游戏规则如下: 1、答案单字写在纸上(每个字元一张纸),并且被盖起来,玩家每次猜一个英文字元(le…

ssh远程执行多个命令
shell远程执行: 经常需要远程到其他节点上执行一些shell命令,如果分别ssh到每台主机上再去执行很麻烦,因此能有个集中管理的方式就好了。一下介绍两种shell命令远程执行的方法。 前提条件: 配置ssh免密码登陆 对于简单的命令&am…

【ACM】魔方矩阵
输出魔方矩阵 1、将1放在第一行中间一列; 2、从2开始直到nn止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1; 3、如果上一个数的行数为1,则下一个数的行数为n(指最下一行&#x…

iOS 秒数转换成时间,时,分,秒
//转换成时分秒 - (NSString *)timeFormatted:(int)totalSeconds{ int seconds totalSeconds % 60; int minutes (totalSeconds / 60) % 60; int hours totalSeconds / 3600; return [NSString stringWithFormat:"%02d:%02d:%02d",hours, minutes,…

charles和Fiddler感觉哪个更好用
1.fiddler还可以抓HTTPS的包,解析出来都可以2.charles更直观,可能是我先用charles的缘故。charles遍历一个站点,可以右键另存,保存全站文件资源。扒站首选, charles也可以抓https,我改游戏也是抓的https包

systemd用法
一、开机启动 对于那些支持 Systemd 的软件,安装的时候,会自动在/usr/lib/systemd/system目录添加一个配置文件。 如果你想让该软件开机启动,就执行下面的命令(以httpd.service为例)。 $ sudo systemctl enable http…

C#实现php的hash_hmac函数
from:http://blog.csdn.net/ciaos/article/details/12618487 PHP代码示例如下<?php $res1 hash_hmac("sha1","signatureString", "secret");echo $res1."\n";//ee1b654aa861c41fd5813dc365ef106c9801f8f6echo base64_encode($res…
【ACM】杭电OJ 2015
注意输出格式!!!! #include <iostream> #include <cstring> using namespace std; int main () {int m,n,i,sum,flag;while(cin>>n>>m){sum0;flag0;for(i1;i<n;i){sum(2*i);flag;if(flagm){sum/m;cou…

AGC002[BCDEF]题解
F是计数于是就做(kan ti jie)了 B - Box and Ball 模拟一下 每个盒子开一个d表示有的球数 可能存在红球的打个标记 传递一下就行了 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define inf 2002…

物联网11种通信协议
今天的网络通信技术也是日新月异,有众所周知的WIFI、Bluetooth、Zigbee、2G、3G、4G蜂窝网络,也有新兴的LiFi、AirGig、量子通信等,更有物联网产业爆发前夜,市场衍生出来的一些比较有前景的通信技术,如以窄带物联网NB&…

php 数组的使用
2019独角兽企业重金招聘Python工程师标准>>> 一、字符串和对象,数组之间的相互转换 public function index(){$product array();$product["name"] "apple";$product["price"] 6000;$products array();$products[] $pr…

【ACM】图像旋转
逆时针 //图像旋转 #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; int main () {int a[105][105];int m,n,i,j;while(scanf("%d%d",&n,&m)!EOF)//n行m列 {for(i0;i<n;i…
do一下来了一个redux
导语 一开看redux的时候还是比较蒙的,感觉比较绕,但是又好像是那么回事,接触一个新概念的时候可能都是如此,多去接触就熟悉了,今天就来分享下redux的三大核心为什么就能如此神奇的施展魔法,干撸完源码&…
JavaMail API 概述
JavaMail API提供了一种与平台无关和协议独立的框架来构建邮件和消息应用程序。 JavaMail API提供了一组抽象类定义构成一个邮件系统的对象。它是阅读,撰写和发送电子信息的可选包(标准扩展)。 JavaMail 规定,用于构造一个接口&am…

利用c语言结构体和union实现类似c++的public,private的实现
最近在看strongswan源代码,看到strongswan的代码框架很有意思,用C语言实现类的思想。当我们编写完一个模块,我们需要提供的是H的文件给其他模块使用,我们希望H文件中就只能包含一些公有函数,和一些类型的申明ÿ…

【ACM】连续出现的字符
【描述】给定一个字符串,在字符串中找到第一个连续出现k次的字符 【输入】第一行包含一个正整数k,表示至少需要连续出现的次数。1<k<1000。第二行包含需要查找的字符串。字符串的长度在1到1000之间,且不包含任何空白字符。 【输出】若…

Django使用数据库(Mariadb/Mysql)
Django默认使用SQLite作为数据库,配置文件在settings.py 让我们来看一下 """ Django settings for test1 project.Generated by django-admin startproject using Django 2.1.4.For more information on this file, see https://docs.djangoproject.…

I2C和SPI总线优缺点对比
IIC vs SPI现今,在低端数字通信应用领域,我们随处可见IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种通信协议非常适合近距离低速芯片间通信。Philips(for IIC)和Motorola(…

查看CentOS的网络带宽出口
检查维护系统的时候,经常会要查看服务器的网络端口是多大的,所以需要用到Linux的一个命令。 如何查看CentOS的网络带宽出口多大?可以用下面的命令来查看。 # ethtool eth0 前面是命令,后面跟的是设备名,如果对外连接的…

【ACM】删数问题(待更)
【描述】键盘输入一个正整数N,去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的N和S寻找一种方案使得剩下的数字组成的新数最小。(N不超过240位,N>S) 【输入】两行,第一行…

2019,商业智能的10大未来趋势
2019独角兽企业重金招聘Python工程师标准>>> 当我们深思熟虑接下来会发生什么时,Tableau 收集了来自内外部专家的广泛意见。内部专家们把握着行业的脉搏,并与世界各地成千上万的客户接洽交流;外部专家们则与众多数据团队并肩作战&…

c语言信号机制以及中断
用户态到内核态切换途径: 1:系统调用 2:中断 3:异常 中断类型分为如下两大类: 一、强迫性中断:正在运行的程序所不期望的,来自硬件故障或外部请求。 1、I/O 中断:来自…

【ACM】纸牌搭建
【题目】现有N张扑克牌,最多可以搭建几层 【题目分析】找到通项公式 f[ i ]f[ i-1 ]3*i-1。先打出表,再二分搜索。不断缩小范围。 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using na…

DataBase 之 拉链表结构设计
一、概念 拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。 在历史表中对客户的一生的记录可能就这样几条记录,避免了按每…

给每个函数写一个记录日志的功能.
# 功能要求: 每一次调用函数之前, 要将函数名称, 时间节点记录到log的日志中.# 所需模块:# import time## def logger(fn):# def inner(*args, **kwargs):# # fn.__name__ # 函数名字# f open("log", mode"a", encoding"utf-8&q…