当前位置: 首页 > 面试题库 >

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

洪伟彦
2023-03-14
问题内容

标题中的问题很多:就操作系统级别的实现而言,共享库和dll有何不同?

我之所以这样问,是因为我最近阅读了有关扩展Python的页面,其中指出:

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

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

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

有人可以详细说明吗?具体来说,我不确定我是否理解共享对象的描述,其中包含对共享对象的期望引用。同样,DLL听起来对我来说几乎是相同的机制。

这是对发生的一切的完整解释吗?有更好的吗?实际上有什么区别吗?

我知道如何链接到DLL或共享对象以及一些用于编写DLL的机制(.def清单,dllexport /
dllimport),因此,我明确地不打算在这些领域中寻找方法。我对后台发生的事情很感兴趣。

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


问题答案:

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

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

另一方面,Dll文件是一种操作系统功能,与语言的链接步骤完全分开。MSVC使用.lib文件来链接静态库和动态库(每个dll文件都会生成一个用于链接的成对的.lib文件),因此,一旦生成该程序,就将其完全“链接”(从语言中心角度)。

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



 类似资料:
  • 问题内容: 我参与了有关Linux库的一些辩论,并想确认一些事情。 以我的理解(如果我做错了请纠正我,稍后我将编辑我的文章)在构建应用程序时有两种使用库的方式: 静态库(.a文件):在链接时,会将整个库的副本放入最终应用程序中,以便调用方应用程序始终可以使用库中的功能 共享对象(.so文件):在链接时,仅通过相应的标头(.h)文件针对其API验证了对象。该库直到需要运行时才真正使用。 静态库的明显

  • 我试图将我编译的简单共享库(libhello.so)链接到我的本机C++代码中。库libhello.so文件是: 1。Get13.h 2.get13.cpp Android文件是: 1。myapplication/jni/android.mk 问题是,在gradle构建过程中,我在文件native-lib.cpp中得到了这个错误: 我使用android NDK包中包含的make_standalon

  • 本文向大家介绍静态库和共享库之间的区别,包括了静态库和共享库之间的区别的使用技巧和注意事项,需要的朋友参考一下 在编程上下文库中是一种具有某种代码的东西,这些代码已经过预编译,可以在任何程序中重新使用以实现某些特定功能或特性。 现在,根据该代码库的执行和存储,将其分为两种类型,即静态库和共享库。 以下是静态库和共享库之间的重要区别。 序号 要点 静态库 共享库 1 定义 静态库是一个库,其中执行文

  • 在window环境上python能不能调用在linux环境中编译出来的共享库(动态库)so文件?

  • 我正在尝试链接一个名为libtest lib的预编译共享库文件。所以这是我在CMakeLists的底部所拥有的。txt: 如上所述,我得到以下错误: 如果我注释掉add_library行,我会得到以下结果: 在库中链接时,似乎绝对需要源文件(.c、cpp等)。但我如何在一个。那档案呢?这些文档对target_link_库()做了如下介绍: 被命名的必须是由add_executable()或add_

  • 问题内容: 我正在尝试建立一个共享库。让我们说libabc.so。它使用另一个.so文件,例如lib123.so(/ usr / local / lib中的一个lib)。现在我在我的应用程序中使用共享的liblibabc.so。说我的应用程序。我想知道我应该如何链接这些二进制文件?我不想直接将我的应用程序与lib123.so链接。my- app应该仅与libabc.so链接。我怎样才能做到这一点?