Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 架构上,共享对象(SO)和动态链接库(DLL)之间有什么区别?_Windows_Linux_Dll_Operating System_Shared Libraries - Fatal编程技术网

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

Windows 架构上,共享对象(SO)和动态链接库(DLL)之间有什么区别?,windows,linux,dll,operating-system,shared-libraries,Windows,Linux,Dll,Operating System,Shared Libraries,问题就在标题中:就操作系统级实现而言,共享对象和DLL有什么不同 我问这个问题的原因是因为我最近阅读了关于扩展Python的文章,其中指出: Unix和Windows在运行时加载代码时使用完全不同的范例。在尝试构建可动态加载的模块之前,请了解系统的工作方式 在Unix中,共享对象(.so)文件包含程序要使用的代码,以及它希望在程序中找到的函数和数据的名称。当文件连接到程序时,文件代码中对这些函数和数据的所有引用都将更改为指向程序中函数和数据存储在内存中的实际位置。这基本上是一个链接操作 在Win

问题就在标题中:就操作系统级实现而言,共享对象和DLL有什么不同

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

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

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

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

有人能详细说明一下吗?具体来说,我不确定我是否理解共享对象的描述,其中包含对它们期望找到的内容的引用。类似地,DLL对我来说听起来几乎是相同的机制

这是对正在发生的事情的完整解释吗?有更好的吗?事实上有什么不同吗

我知道如何链接到DLL或共享对象,以及用于编写DLL的两种机制(.def listings,dllexport/dllimport),因此我不想在这些领域中明确寻找操作方法;我对背景中发生的事情更感兴趣


(编辑:另一个明显的问题——我知道它们在不同的平台上工作,使用不同的文件类型(ELF与PE),ABI不兼容等等。)

Dll与.so或.dylib(MacOS)文件使用的机制几乎相同,因此很难准确解释它们之间的区别

核心区别在于默认情况下,每种文件类型的内容都是可见的。所以文件导出语言(GCC)级链接-这意味着(默认情况下)所有“C++”符号都是“Extn”,当SO被拉入时,它们可以用于链接。 这还意味着,解析.so文件本质上是一个链接步骤,加载程序不关心符号来自哪个.so文件。它只是按照.a文件遵循的常规链接步骤规则,按一定顺序搜索指定的.so文件

另一方面,Dll文件是一种操作系统功能,完全独立于语言的链接步骤。MSVC使用.lib文件链接静态库和动态库(每个dll文件生成一个用于链接的成对.lib文件),因此生成的程序在构建后即完全“链接”(从以语言为中心的角度)


但是,在链接阶段,在表示dll的库中解析了符号,从而允许链接器在PE文件中构建导入表,其中包含dll的显式列表和每个dll中引用的入口点。在加载时,Windows不必执行“链接”来解析共享库中的符号:这一步已经完成-Windows加载程序只需加载dll并直接连接函数。

dll已关闭,其所有符号都已解析(链接器知道在何处找到它们)。这听起来很奇怪。DLL当然有悬空引用。他们需要由加载器解决。很抱歉,错误地发送了评论,无法编辑。当然,DLL可以有悬空引用,但DLL知道每个引用指向的位置(其他特定DLL)。而对于.so,悬空引用是由具有该名称的第一个符号解析的,无论它位于何处。如果它恰好在可执行文件本身中,而不是在任何其他文件中。那么,这也没关系。我明白了,我认为这是有道理的。我将把这个问题留待一两天,看看它是否能吸引到更多的详细答案,但我想我从这一点上理解了它。再次感谢。但是在windows上不可能有多个可互换的DLL(即相同的接口,不同的实现)吗?如果DLL中符号的位置被烘焙到可执行文件中,那么两个DLL如何具有相同的接口,而不使这些符号位于相同的位置?还是在同一个地方?或者,这种功能只在
loadLibrary
等情况下才可能实现?@cheshirekow:对于静态链接DLL(由包含库解析的DLL),地址已固定=>替换DLL必须具有每个导出函数的相同地址。对于动态加载的DLL(例如,
LoadLibrary
COM
,…)
getprocadres()
在运行时手动解析地址=>!