我问的原因是因为我最近读了this page扩展Python,其中规定:
Unix and Windows use completely different paradigms for run-time loading of code. Before you try to build a module that can be dynamically loaded,be aware of how your system works.
In Unix,a shared object (.so) file contains code to be used by the program,and also the names of functions and data that it expects to find in the program. When the file is joined to the program,all references to those functions and data in the file’s code are changed to point to the actual locations in the program where the functions and data are placed in memory. This is basically a link operation.
In Windows,a dynamic-link library (.dll) file has no dangling references. Instead,an access to functions or data goes through a lookup table. So the DLL code does not have to be fixed up at runtime to refer to the program’s memory; instead,the code already uses the DLL’s lookup table,and the lookup table is modified at runtime to point to the functions and data.
有人可以详细说明一下吗?具体来说,我不知道我理解共享对象的描述,包含对他们期望找到的内容的引用。类似地,一个DLL听起来和我一样的机制。
这是对发生了什么的完整解释吗?有更好的吗?有没有什么区别?
我知道如何链接到一个DLL或共享对象和几个机制(.def列表,dllexport / dllimport)用于编写DLL,所以我明确地不寻找一个如何在这些领域;我对背景中发生的事情更感兴趣。
(编辑:另一个明显的点 – 我知道他们在不同的平台上工作,使用不同的文件类型(ELF对PE),ABI不兼容等)
核心区别在于默认情况下,每种类型的文件都可见。 .so文件导出语言(gcc)级别的链接 – 这意味着(默认情况下)所有C& C语言中的“extern”可用于链接.so被插入。
这也意味着,当解析.so文件本质上是一个链接步骤时,加载程序不关心符号来自哪个.so文件。它只是按照.a文件遵循的常规链接步骤规则,按照某些顺序搜索指定的.so文件。
另一方面,Dll文件是一个操作系统功能,与语言的链接步骤完全分开。 MSVC使用.lib文件链接静态和动态库(每个dll文件生成一个用于链接的配对的.lib文件),因此生成的程序一旦建立就完全“链接”(从语言为中心的角度) 。
然而,在链接阶段,在表示Dll的lib中解析了符号,允许链接器在PE文件中构建导入表,其中包含dll的显式列表和每个dll中引用的入口点。在加载时,Windows不必执行“链接”来解决共享库中的符号:该步骤已经完成 – Windows加载器只是加载dll并直接挂接这些函数。