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 .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...
随机推荐
- The square chest
The square chest Sophia pressed the button in front of her, slamming her fist against it. The door r ...
- 异步化DAO的设计和实践
目前,公司技术规划要求未来所有的服务要全面实现异步化接口,使得每个服务能达到1万/秒的单机性能.我们知道,在一个服务请求中,可能会调用其他服务,还会使用memcache.kv以及mysql等.目前,大 ...
- Direct3D 索引缓存
小学的时候我们知道3个顶点组成一个三角形,那么四个顶点我们会说有4个三角形.这就是一个顶点同时参与了四次绘制三角形的结果. 在程序中也一样,比如我们绘制的两个三角形是挨着一起的,总有几个顶点是重合的. ...
- python高级编程之访问超类中的方法:super()
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #超类01 #它是一个内建类型,用于访问属于某个对象超类特性 pri ...
- web前端之 HTML标签详细介绍
html标签的分类 点我查看完整的html标签介绍 在html中,标签一般分为块级标签和行内标签 块级标签:块元素一般都从新行开始,它可以容纳内联元素和其他块元素,常见块元素是段落标签"p& ...
- jdbc和数据库的应用
jdbc是Java Data Base Connectivity(java数据库连接): 是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和 ...
- php创建带logo的二维码
<?php /** php使用二维码 **/ class MyQrcode{ const SIZE = 150; const LEVEL = "L"; const MARGI ...
- C++ - 容器(container)的erase()函数
容器(container)的erase()函数 本文地址: http://blog.csdn.net/caroline_wendy/article/details/23996013 容器(contai ...
- 一个用 Cumulative Penalty 培训 L1 正规 Log-linear 型号随机梯度下降
Log-Linear 模型(也叫做最大熵模型)是 NLP 领域中使用最为广泛的模型之中的一个.其训练常採用最大似然准则.且为防止过拟合,往往在目标函数中增加(能够产生稀疏性的) L1 正则.但对于 ...
- 又一道软通动力7K月薪面试题——银行业务调度系统
后期补充:网友对我诟病最多的就是我帮学生做面试题,说这是小偷和骗子行为,在此,我对自己给学员做面试题做出例如以下解释: (1)学员拿着面试题来找老师,学生也事先思考和尝试后实在没有办法,又求职心切才 ...