我应该将Visual Studio C运行时链接静态还是动态?

23

我已经阅读了关于在Visual Studio项目中静态链接还是动态链接C运行时库的双方观点,但我仍不确定该如何看待此问题。

我的项目引用了一些第三方库(Python、HDF5、Trilinos和Microsoft MPI),每个库都必须使用与最终可执行文件相同的运行时库进行构建(否则它们无法链接在一起)。当静态链接时,每个库将包含一个C运行时库的副本。我读到说这可能会导致问题,因为最终的可执行文件将包含多个运行时库的副本,而且这些副本都无法彼此交互。但是,如果相同符号被多次定义,链接器不会报错吗?

我想避免“DLL地狱”,但我担心静态链接多个运行时库的副本可能引发隐蔽的错误。我是否理解有误?

此外,我正在使用Visual Studio 2005,我读到Service Pack 1运行时库不向后兼容。这是否意味着没有安装SP1的应用程序将无法在具有SP1 dlls的计算机上运行,即使它们具有相同的名称(例如msvcr80.dll)?

4个回答

27

静态链接会使你的EXE和DLL变得臃肿,并且可能会导致崩溃(例如,一个DLL中的代码使用由另一个DLL中的malloc()分配的指针调用free()函数)。

你可以采用动态链接的方式,同时将运行时DLL作为私有程序集进行部署。这意味着将一个包含运行时DLL及其清单文件的特殊命名目录的副本放置在你的可执行文件旁边。

具体细节请参见“将Visual C++库DLL作为私有程序集部署”一节,网址为http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx,但基本上你的应用程序看起来像这样:

c:\Program Files\My App\MyApp.exe
c:\Program Files\My App\MyLibrary.dll
c:\Program Files\My App\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest
c:\Program Files\My App\Microsoft.VC80.CRT\msvcr80.dll

针对您的最后一个问题,是的,目标计算机需要正确版本的运行时DLL才能正常工作,但通过将它们部署为私有程序集,您可以确保这一点。

另一个好处是非管理员用户可以安装您的应用程序(不安装在Program Files中,而是其他位置),他们不需要许可权限来将文件写入WinSxS区域。


这就是我一直在寻找的答案。私有程序集似乎是解决我的问题最安全的方法。有点像Mac捆绑包,一个应用程序被分发在一个固定的目录结构中。谢谢! - user76293
8
但是私有程序集不会被 Windows 更新程序打补丁,对吧?因此,您需要自己及时更新运行库的副本。另请参见http://blogs.msdn.com/larryosterman/archive/2004/04/29/123090.aspx。 - David Citron
1
如果我的“应用程序”(My App)文件夹包含混合的32位和64位应用程序,我从未使这些私有程序集工作。你不能简单地向程序集文件夹名称添加类似于x32或x64的内容,这意味着只有在您只有32位或只有64位应用程序时才能使用私有程序集。 - Patrick
2
不,您不必自己更新私有运行时。在使用私有程序集之前,始终首先检查WinSxS。如果它有更新版本,系统会自动使用它。 - Amit Naidu
@AmitNaidu 你确定吗?我认为 WinSxS 的重点是每个应用程序使用自己的版本。 - Navin

13

仅当您将库静态链接到DLL时,才会获得多个运行时的副本-每个DLL都会获得一份副本,exe也会获得一份。如果它们全部是静态库而不是DLL,则它们将全部链接在一起,所有库都将共享相同的运行时。

这是链接器的工作。


1
静态库不需要与其他静态库进行静态链接。你只需要在主项目中链接所有的静态库。这样编译器就不会报告多个符号的冲突。

1
澄清一下:我不会将库链接到彼此,当我链接我的主可执行文件时,我也不会得到多次定义的符号。但是我不确定我的可执行文件中是否有多个C运行时副本,这是静态链接到它时发生的情况(根据我所读的内容的解释,可能是错误的)。 - user76293

1

...以静态方式实现...尝试解决 DLL Hell 的尝试并没有取得很好的效果...只需使用静态链接,将额外增加 200k 的安装文件。


你对运行时的多个副本有什么想法?这是我的真正问题。 - user76293
1
无论如何,运行时将会有多个副本。这就是WinSxS文件夹的作用(它是为了解决DLL地狱而尝试的)。虽然这很令人困惑,但打包自己的运行时将避免这些问题。 - CookieOfFortune

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接