静态链接的优点

时间:2008-11-23 11:24:12

标签: c# linker

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

不久前,我的一位朋友已经编程了好几年,感到遗憾的是C#没有静态链接,并说这是他未来版本最需要的功能。不幸的是,我是一个新手,并不真正理解这个说法。

感谢任何启蒙!

5 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:7)

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

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

thread也可以解决您的问题。

答案 2 :(得分:6)

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

现在,如果你想在.NET中静态链接东西,你可以

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

我确信有一种聪明的方法可以避免这些问题,但我不太清楚在.NET或Java等托管环境中静态链接的问题。我的意思是,静态链接确实提高了性能,但不是那么多。而且我们不会使用托管语言来执行它们的速度。

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

答案 3 :(得分:3)

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

  • 您无需安装任何其他内容。只需复制并运行。或者跑到原处。没有安装程序,没有警告,没有由于错误的DLL版本导致的奇怪错误。就是这样。
  • 您的用户也可以享受这种简约。这通常更重要。没有人欢迎安装依赖项。特别是如果它像.NET框架一样巨大。

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

答案 4 :(得分:1)

静态与动态链接之间存在差异的一个很好的例子。如果您查看InkScape项目,您将找到InkscapePortable和InkScape。 InkscapePortable将运行USB记忆棒。 InkScape不会。