WIN下和LINUX动态库的区别
**************************************************************************************************************************************
转载:http://blog.codingnow.com/2006/11/windows_unix_dynamic_library.html
最近慢慢将开发环境转向了 freebsd ,渐渐的发现了许多东西跟 Windows 下不太一样。我指的是,跟我以前想当然的理解不太一样。比如,unix 下对动态链接库 so 的处理,和 Windows 下的 DLL 就不太相同。
之前,我对 Windows 下更为了解一些。早几年做 Windows 开发,老是为动态链接,静态链接这些问题纠缠不清;慢慢的才有了比较清晰的理解,现在基本上不会为这类问题困绕了。前段时间,碰到一些朋友写 lua 的扩展库(windows 版本)时遇到的几个 bug ,就是因为链接问题导致的。公司内部的一个项目,在服务器程序上也碰到了错误链接 lua 引起的 bug ,在内部 maillist 上争论了好久。当时,作为 windows 程序员,跟同事中的 unix 程序员争论看似相同的问题时,却老说不到一起去;今天才发现,原来是相互之间对动态链接库的理解不同导致的。
今天,写下本文,或许可以让以后跨平台开发的朋友少走点弯路。
动态链接库在 unix 下,习惯以 .so 为文件名结尾(通常还以 lib 开头)。而 Windows 下是以 .DLL 为文件后缀。Windows 在处理 dll 上还有一些细节容易被人忽略,我曾经为这个写过一篇 Blog。
如果需要运行时主动加载一个动态链接库,windows 下可以使用 LoadLibrary 这个 kernel API (在 kernel32.dll 中);unix 下是用 dlopen 。Windows 下找到 dll 中导出符号的地址,可以用 GetProcAddress ,而 unix 也有对应的 api ...
这些相互对应的 api ,似乎预示着对等的功能,但事实上是有区别的。
DLL 事实上和 EXE 文件一样,同属 PE 格式的执行文件。对于隐式的引用外部符号,需要把外部符号所在的位置写在 PE 头上。PE 加载器将从 PE 头上找到依赖的符号表,并加载依赖的其它 DLL 文件。
但是,unix 上并非如此,so 文件大多为 elf 执行文件格式。当它们需要的外部符号,可以不写明这些符号所在的位置。也就是说,通常 so 文件本身并不知道它依赖的那些符号在哪些 so 里面。这些符号是由调用 dlopen 的进程运行时提供的。而 unix 下的执行文件本身会暴露自己静态链接的符号,(可以是自己本身实现的,或者是从静态库 .a 文件里链入的)。dlopen 将把这些符号通报给 dlopen 加载的 .so 文件,最终完成动态链接。(事实上 dlopen 还可以指定 mode ,完成更复杂的操作)
因为这个区别,unix 下的 lua 解释器可以完全静态链接所有的 lua api ;我们为 lua 扩展的库,以 so 的形式存在被运行时加载不会有任何隐患。而 Windows 下,必须生成一个 luacore 的 DLL 文件,由 lua 解释器于扩展库共享 lua api (还包括 crt 的实现) 才不会出问题。
也因为这个区别,VC 下才会有让 windows 开发新手困惑不解的动态链接 CRT ,静态链接 CRT ,多线程库,单线程库,等等的选项。没点点 windows 开发功力的人,多少都要在上面栽几个跟头。
从动态链接库的这个设计上来看,我个人感觉,Windows 弄的真是糟糕透顶。尤其是对开发者来说是这样。至少我们在 windows 下做一个 dll 文件给大家使用还需要携带一个 .lib 文件;而 unix 下一般只需要有相应的头文件就够了。对于编写新的 .so ,找不到的符号可以就让它在那里,直到最终执行文件来把所有需要的符号联合到一起。windows 可以存在一个 dll 对另一个 dll 的隐式依赖;而 unix 下一般不需要让 so 和 so 有隐式依赖关系。这让我们全局替换类似 CRT 的东西变的困难许多;而以我自己的编程经验来看,好处却没有多少。
顺便一提的是 unix 下需要用 ldconfig 来管理动态库,这比 windows 下 copy DLL 到当前目录下就可以用的方式,无疑提高了系统的安全性。
references:
http://stackoverflow.com/questions/2649334/difference-between-static-and-shared-libraries
http://stackoverflow.com/questions/9688200/difference-between-shared-objects-so-static-libraries-a-and-dlls-so
WIN下和LINUX动态库的区别的更多相关文章
- 静态库和动态库的区别和win平台和linux平台代码实现
静态库和动态库的区别 什么是库 库是写好的,现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说,库是一种可 ...
- iOS 静态库和动态库的区别&静态库的生成
linux中静态库和动态库的区别 一.不同 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函 ...
- 技巧:Linux 动态库与静态库制作及使用详解
技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...
- linux动态库加载RPATH, RUNPATH
摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...
- windows动态库与Linux动态库
Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须 ...
- linux动态库编译和使用详细剖析 - 后续
引言 - 也许是修行 很久以前写过关于动态库科普文章, 废话反正是说了好多. 核心就是在 linux 上面玩了一下 dlopen : ) linux动态库编译和使用详细剖析 - https://www ...
- VS中Debug和Realease、及静态库和动态库的区别整理(转)
原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...
- VS中Debug和Realease、及静态库和动态库的区别整理
一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序在代码 ...
- linux动态库默认搜索路径设置的三种方法
众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...
随机推荐
- Linux 下的下载文件命令
普通文件只需 wget fileAddr 下载带有登录验证的文件 [chen@localhost Downloads]$ wget --user='av\bname' --ask-password ...
- mook_百度百科
mook_百度百科 mook
- UGUI 快捷键创建UGUI组件
使用NGUI的时候还有xxx快捷键创建, spirte,label,button等等. 在UGUI里面的时候好像是没有快捷键的. 不知道以后多久才能有这个功能. 在家里闲无聊的时候写了一个脚本, ...
- Spark常用函数讲解之Action操作
摘要: RDD:弹性分布式数据集,是一种特殊集合 ‚ 支持多种来源 ‚ 有容错机制 ‚ 可以被缓存 ‚ 支持并行操作,一个RDD代表一个分区里的数据集RDD有两种操作算子: Trans ...
- [Ext JS 4] 实战之Grid, Tree Gird编辑Cell
前言 本篇这里以稍微复杂一点的Tree Grid 来介绍. 在写编辑grid 之, 先来看一下 grid 的 selType 的配置. 先给一个简单的Tree grid 的例子: Ext.onRead ...
- nodejs之简介及安装(一)
@[nodejs|个人学习笔记] nodejs简介 什么是node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. 参考网站 一.nodejs.cn 二 ...
- Chrome开发者工具详解(3):Timeline面板
Timeline面板 Timeline面板是整个面板里面最复杂的一个面板,涉及的东西比较多.可以利用这个面板来记录和分析网页运行过程中的所有活动行为信息. 你可以充分利用这个面板来分析你的网页的程序性 ...
- jQuery中click()与trigger方法的区别
click()可以执行单击事件,但是不可传参. $("button").click(function(){ alert("hello."); }); trigg ...
- android隐式intent使用场景解析
Android 隐式intent相信大家都有用过,大部分场景我们用显式intent已经能满足我们的业务需求,隐式intent大部分都是用来启动系统自带的Activity或Service之类的组件.昨天 ...
- 【转载】"library not found for - "解决办法
[摘要:正在我们编译的时间偶然候会报那个毛病"library not found for - " 因为是我们正在项目中应用了一些第三圆的库,便比方我再应用百度的静态库文件的时间,报 ...