**************************************************************************************************************************************

转载: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动态库的区别的更多相关文章

  1. 静态库和动态库的区别和win平台和linux平台代码实现

    静态库和动态库的区别   什么是库 库是写好的,现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说,库是一种可 ...

  2. iOS 静态库和动态库的区别&静态库的生成

    linux中静态库和动态库的区别 一.不同 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函 ...

  3. 技巧:Linux 动态库与静态库制作及使用详解

    技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...

  4. linux动态库加载RPATH, RUNPATH

    摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...

  5. windows动态库与Linux动态库

    Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须 ...

  6. linux动态库编译和使用详细剖析 - 后续

    引言 - 也许是修行 很久以前写过关于动态库科普文章, 废话反正是说了好多. 核心就是在 linux 上面玩了一下 dlopen : ) linux动态库编译和使用详细剖析 - https://www ...

  7. VS中Debug和Realease、及静态库和动态库的区别整理(转)

    原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...

  8. VS中Debug和Realease、及静态库和动态库的区别整理

    一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序在代码 ...

  9. linux动态库默认搜索路径设置的三种方法

    众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...

随机推荐

  1. qt info.plist 添加

    http://www.waitingfy.com/archives/1242 http://www.sollyu.com/settings-icon-under-the-qt-mac-applicat ...

  2. android UI之Shape详解_GradientDrawable

    在Android开发过程中,经常需要改变控件的默认样式, 那么通常会使用多个图片来解决.不过这种方式可能需要多个图片,比如一个按钮,需要点击时的式样图片,默认的式样图片. 这样就容易使apk变大. 那 ...

  3. 解决SQL server不支持utf8,php却用utf8的矛盾问题

    function convert2utf8($string) { return iconv("gbk","utf-8",$string); } function ...

  4. [转]ReactJS入门教程

    Refference From:http://www.cocoachina.com/webapp/20150721/12692.html 现在最热门的前端框架有AngularJS.React.Boot ...

  5. maven 工作原理和添加jar包技巧

        相 信只要做过 Java 开发的童鞋们,对 Ant 想必都不陌生,我们往往使用 Ant 来构建项目,尤其是涉及到特别繁杂的工作量,一个 build.xml 能够完成编译.测试.打包.部署等很多 ...

  6. 集合操作出现的ConcurrentModificationException(源码分析)

    摘要: 为了保证线程安全,在迭代器迭代的过程中,线程是不能对集合本身进行操作(修改,删除,增加)的,否则会抛出ConcurrentModificationException的异常. 示例: publi ...

  7. mysql 自己定义存储过程和触发器

    mysql 自己定义存储过程和触发器 --存储过程示范 DROP PROCEDURE IF EXISTS PRO_TEST; CREATE PROCEDURE PRO_TEST(IN NUM_IN I ...

  8. [Hapi.js] Request Validation with Joi

    hapi supports request validation out of the box using the joi module. Request path parameters, paylo ...

  9. [Immutable.js] Using fromJS() to Convert Plain JavaScript Objects into Immutable Data

    Immutable.js offers the fromJS() method to build immutable structures from objects and array. Object ...

  10. ASP.NET 导出Excel文档

    System.IO.TextWriter writer = new System.IO.StreamWriter(Server.MapPath("/provprice.xls"), ...