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

use*_*293 19 crt msvcrt

我已经阅读了双方关于是否应该在Visual Studio项目中静态或动态地链接到C运行时库的参数,并且我仍然不完全确定要考虑什么.

我的项目引入了一些第三方库(Python,HDF5,Trilinos和Microsoft MPI),每个库都必须使用与我的最终可执行文件相同的运行时库构建(否则它们不能链接在一起).静态链接时,每个库都将包含C运行时的副本.我读到这很容易引起问题,因为最终的可执行文件将包含运行时的多个副本,其中没有一个可以相互交互.但是,如果相同的符号被多重定义,链接器是否会抱怨?

我想避免"DLL Hell",但我担心在运行时的多个副本中静态链接可能会产生的阴险错误.我读错了吗?

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

Ric*_*dle 25

静态链接会使所有EXE和DLL膨胀,并且可能导致崩溃(例如,如果一个DLL中的代码使用malloc()在不同的DLL中分配的指针调用free()).

通过动态链接和将运行时DLL部署为私有程序集,您可以充分利用这两个方面.这只是意味着将包含运行时DLL及其清单的特殊命名目录的副本放在可执行文件旁边.

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx上的 "将Visual C++库DLL部署为私有程序集"一节,但基本上您的应用程序如下所示:

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
Run Code Online (Sandbox Code Playgroud)

至于你的上一个问题,是的,目标机器需要正确版本的运行时DLL才能工作,但是通过将它们部署为私有程序集,你可以保证.

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

  • 但是Windows Update不会修补私有程序集,对吗?因此,您必须自己更新运行时库的副本.另见http://blogs.msdn.com/larryosterman/archive/2004/04/29/123090.aspx (7认同)
  • 不,您不必自己更新私有运行时.在使用专用程序集之前,始终先检查WinSxS.如果它有更新版本,它将自动使用. (2认同)

Mar*_*som 12

你将获得运行时的多个副本的唯一时间是当你将库静态链接到DLL时 - 每个DLL都会获得一个副本,exe也是如此.如果它们都是静态库而不是DLL,它们将全部链接在一起,并且所有库将共享相同的运行时.

这是链接器的工作.