【问题标题】:Static linking advantages静态链接优势
【发布时间】:2010-09-23 16:01:18
【问题描述】:

我最近在这里阅读了一个关于静态和动态链接的问题,这让我想起了一些关于它的问题。从那篇文章中,我可以看到技术差异是什么(直接包括目标文件内容,而不是仅仅指向它),但我想更多地了解这样做的利弊。

不久前,我的一位从事编程多年的朋友感叹 C# 不是静态链接的,并说这是他未来版本最想要的功能。不幸的是,我是新手,并不真正理解这种说法。

感谢您的启发!

【问题讨论】:

    标签: c# linker


    【解决方案1】:

    静态链接的优势在于它消除了对库的外部依赖 - 即,您正在使用的库的行为永远不会改变,因为有人更改了磁盘上的库。这也是静态链接的缺点之一。如果操作系统发生变化并且需要新版本的库才能正常工作,则必须提供二进制文件的升级版本。同样,如果将错误修复添加到库中,如果您已静态链接,则不会自动获得该错误修复。

    大多数(事实上,可能是所有这些天)操作系统都可以为多个进程加载一个动态库的副本,这就是为什么在 UNIX 上它们被称为共享对象。

    【讨论】:

      【解决方案2】:

      静态可执行文件包含它需要的所有对象,因此在执行时不会调用外部 DLL。优点是可以跨许多平台移植,无论该系统上安装了什么版本的 DLL。最大的缺点是您可能会浪费磁盘空间,因为您包含在系统/外部 DLL 中已经存在的可执行代码中。此外,我认为,但我不太确定,DLL 在主内存中只加载一次,无论有多少可执行文件正在使用它们,但是如果你静态链接可执行文件中的库对象,你会加载相同的代码两次(一个用于其余程序使用的 DLL 和一个用于您的可执行文件的 DLL)。另一方面,这可能是一个优点,而不是一个缺点,因为可执行文件只包含它需要的外部库的对象,而不是整个库。当应用程序需要时,DLL 会作为一个整体加载到内存中。

      静态链接非常适合编译您希望作为小工具从一个系统携带到另一个系统的小型应用程序。 IE。当它没有包含在每个 Linux 发行版中时,拥有一个静态编译版本的 tcpdump 对我来说真的很有用。无论内核、glibc 或其他系统库有什么版本,它都必须在每个 Linux 上工作。也许它在 Windows 世界中没有多大意义,因为平台更加同质化。如果您为 Windows XP / NET vX.X 进行编译,它将适用于许多计算机。如果您为 Debian X.X 编译某些东西,它肯定无法在较旧/较新的 Debian 或 Redhat 等其他发行版上运行。

      这个thread也可以解决你的问题。

      【讨论】:

        【解决方案3】:

        老实说,出于一百万个原因,我不确定静态链接在 C# 中是否真的是一个好主意。一个原因是,与 C 或 C++ 等语言相比,C# 具有程序集的概念,程序集基本上是可执行文件或 DLL。

        现在,如果您想在 .NET 中静态链接事物,您也可以

        • 将多个程序集中的类合并到一个程序集中。这会破坏很多东西,比如“internal”访问修饰符。
        • 在同一个可执行文件中有多个程序集。但是,这将使程序集的整个概念变得毫无用处,并且需要重新设计 .NET Framework 中的反射方法。

        我确信有一种巧妙的方法可以避免这些问题,但我不太明白在 .NET 或 Java 等托管环境中进行静态链接的意义。我的意思是,静态链接确实可以提高性能,但并没有那么多。而且我们无论如何也不使用托管语言来提高它们的执行速度。

        另一个问题是 DLL 地狱,但在 .NET 中,这几乎是一个已解决的问题。

        【讨论】:

        • 想要一个 .exe 而不是一个 .exe 和 30 个 .dll 是一个非常好的理由 - 我的客户不应该仅仅因为我想将我的软件重构为多个项目。而且我不明白为什么您所说的 必须 是这样的 - 他们基本上可以将 .dll 存储在 .exe 中,并在需要时像 .dll 一样加载它。没有充分的理由不支持静态链接。
        • 这是一个解决方法,只需确保资源名称指向您的实际程序集:blogs.msdn.com/b/microsoft_press/archive/2010/02/03/…
        【解决方案4】:

        所有需要的东西都打包成一个可执行文件。所以,

        • 您不需要安装任何其他东西。只需复制并运行。或者跑到它所在的地方。没有安装程序,没有警告,没有由于错误的 DLL 版本而导致的奇怪错误。就是这样。
        • 您的用户也可以享受这种简单性。这通常更为重要。没有人欢迎安装依赖项。特别是如果它像 .NET 框架这样庞大。

        当然可执行文件的大小会增加,但它应该比一堆愚蠢的图形文件小。

        【讨论】:

        • 那些认为以牺牲依赖为代价来最小化磁盘空间的人的优先级倒退了
        • @sridhar-sarnobat 是的
        【解决方案5】:

        有一个很好的例子来说明静态链接和动态链接之间的区别。如果您查看 InkScape 项目,您会发现 InkscapePortable 和 InkScape。 InkscapePortable 将使用 USB 记忆棒运行。 InkScape 不会。

        【讨论】:

          猜你喜欢
          • 2012-08-08
          • 1970-01-01
          • 2018-07-26
          • 1970-01-01
          • 2010-12-31
          • 1970-01-01
          • 2017-01-07
          相关资源
          最近更新 更多