在架构上,共享对象(SO)和动态链接库(DLL)之间有什么区别?

18 linux windows dll operating-system shared-libraries

问题在于标题:在操作系统级别的实现方面,共享对象和dll有何不同?

我问这个的原因是因为我最近阅读了关于扩展Python的这个页面,其中指出:

Unix和Windows使用完全不同的范例来进行代码的运行时加载.在尝试构建可动态加载的模块之前,请注意系统的工作方式.

在Unix中,共享对象(.so)文件包含程序要使用的代码,以及它希望在程序中找到的函数和数据的名称.当文件加入程序时,文件代码中对这些函数和数据的所有引用都将更改为指向程序中将函数和数据放入内存的实际位置.这基本上是一个链接操作.

在Windows中,动态链接库(.dll)文件没有悬空引用.相反,对函数或数据的访问通过查找表进行.因此,DLL代码不必在运行时修复以引用程序的内存; 相反,代码已经使用了DLL的查找表,并且在运行时修改了查找表以指向函数和数据.

任何人都可以详细说明吗?具体来说,我不确定我是否理解包含对他们期望找到的内容的引用的共享对象的描述.同样,DLL对我来说听起来几乎是相同的机制.

这是对正在发生的事情的完整解释吗?还有更好的吗?实际上有什么区别吗?

我知道如何链接到DLL或共享对象和几个机制(.def列表,dllexport/dllimport)来编写DLL,所以我明确没有在这些区域寻找如何; 我对后台发生的事情更感兴趣.

(编辑:另一个明显的观点 - 我知道他们在不同的平台上工作,使用不同的文件类型(ELF与PE),ABI不兼容等...)

Chr*_*cke 17

Dll几乎与.so或.dylib(MacOS)文件使用的机制相同,因此很难准确解释差异是什么.

核心区别在于默认情况下每种类型的文件都可见..so文件导出语言(gcc)级别链接 - 这意味着(默认情况下)所有"extern"的C&c ++符号可以在拉入.so时进行链接.它还意味着,作为解析.so文件本质上是一个链接步骤,加载器不关心符号来自哪个.so文件.它只是按照.a文件所遵循的常用链接步骤规则以某种顺序搜索指定的.so文件.

另一方面,DLL文件是操作系统功能,完全独立于语言的链接步骤.MSVC使用.lib文件链接静态和动态库(每个dll文件生成一个用于链接的配对.lib文件),因此生成的程序完全"链接"(从语言中心的角度来看)一旦构建.

然而,在链接阶段,符号在表示Dlls的lib中被解析,允许链接器在PE文件中构建导入表,该表包含dll的明确列表和每个dll中引用的入口点.在加载时,Windows不必执行"链接"来解析来自共享库的符号:该步骤已经完成 - Windows加载器只是加载dll并直接挂起函数.