加载时动态链接和运行时动态链接之间的区别

jen*_*son 24 dll linker operating-system loader toolchain

将程序加载到内存中时,加载时动态链接和运行时动态链接有什么区别?

Aid*_*ell 20

加载时链接是指操作系统将可执行文件/库加载到内存时处理可执行文件(或其他库)引用的库中的符号.

运行时链接是指当您使用OS提供的API或通过库在需要时加载DLL或DSO,然后执行符号解析.

我对Linux DSO的了解比Windows DLL更多,但原理应该是相同的..NET库可能有所不同.

在linux中,插件架构以这种方式完成.您的程序将使用运行时链接来加载库并调用某些函数.然后可能卸载它.它还允许加载具有相同符号导出的多个库而不会发生冲突.我认为DLL的工作方式大致相同.

可执行文件的符号表中有"空格",需要由某些库填充.这些空格通常在加载时或编译时填充.您可以通过使用运行时链接来否定符号表中对"空格"的需要.

运行时链接有用的另一种情况是调试库,或在运行时从多个ABI/API兼容库中进行选择.我经常有一个库,比如"foo"和一个名为"foo_unstable"的库,并且有一个测试应用程序在2之间切换并进行一些测试.

在linux下,要查看可执行文件在加载时链接到哪些库,请运行ldd命令并获取输出,如(on/bin/ls):

linux-vdso.so.1 =>  (0x00007fff139ff000)
librt.so.1 => /lib64/librt.so.1 (0x0000003c4f200000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003c4fa00000)
libcap.so.2 => /lib64/libcap.so.2 (0x0000003c53a00000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003c58e0000
Run Code Online (Sandbox Code Playgroud)

操作系统将尝试在加载时加载库(.so文件).它可能已经在内存中有了库.


Dre*_*all 15

Aiden Bell介绍了基本面,但我会补充:

加载时动态链接通常是通过静态链接应用程序的完成.lib.a包含自动建立运行时的链接符号的代码文件中找到.dll或者.so在程序启动文件.这通常用于固定功能(即C运行时库等),并允许您的程序从库中的错误修复中获益,同时保持较小的可执行文件大小(通过将公共代码分解到单个库中).

运行时链接用于更多动态功能,例如插件加载.正如Aiden所说,您可以使用LoadLibrary()或等效于在运行时将模块主动附加到您的程序,可能是通过询问包含插件DLL的目录,依次加载每个模块并使用自行开发的插件API与它进行交谈.通过这样做,您的程序可以加载在您的应用程序编译/链接时甚至不存在的模块,并且因此可以在部署后有机地增长.

从根本上说,这两种方法最终都会调用LoadLibrary()API,但在前一种情况下使用一组固定的符号和库,在后一种情况下使用更动态的一组.

  • +1为发展/增长利益.模块化架构很酷. (2认同)
  • .Net可执行文件的其他信息:它们使用运行时动态链接.如果在"Dependency Walker"中打开.Net DLL,您可以看到它们只与MSCOREE.DLL加载时动态链接.有关这方面的更多信息,请访问:http://stackoverflow.com/questions/9545603/is-mscorlib-dll-mscoree-dll-loaded-when-net-application-runs如果您参考但不使用DLL和DLL丢失,那么你的应用程序不会出错.您可以在Debug> Windows> Modules中查看当前加载的DLL. (2认同)

smw*_*dia 13

问题问题已经很久了.艾登和德鲁的答案涵盖了大部分内容.我只是想从程序员的角度添加一些东西.

如果使用加载时动态链接,我们必须链接到LIB文件.然后在代码中,我们可以像往常一样明确地调用该方法.(请参阅使用代码示例的加载时动态链接)

如果使用运行时动态链接,则必须自行管理DLL加载/释放和函数查找.(请参阅使用运行时动态链接获取代码示例)

要在两个选项之间进行选择,请选中" 确定要使用的链接方法".

因此,我认为加载时动态链接只是节省程序员工作量的另一种方法.但它的代价是一些可扩展性.您只能使用与用作导入库的LIB文件对应的DLL.

从根本上说,这两种链接方法都使用Windows平台上的LoadLibrary()API.