我已经阅读过关于是否应该在Visual Studio项目中静态或动态地链接到C运行时库的参数,并且我仍然不完全确定要考虑什么。
我的项目引入了一些第三方库(Python,HDF5,Trilinos和Microsoft MPI),每个库都必须使用与我的最终可执行文件相同的运行时库构建(否则它们无法链接在一起)。静态链接时,每个库都将包含C运行时的副本。我读到这很容易引起问题,因为最终的可执行文件将包含运行时的多个副本,其中没有一个可以相互交互。但是,如果相同的符号被多重定义,链接器是否会抱怨?
我想避免“DLL Hell”,但我担心在运行时的多个副本中静态链接可能会产生的阴险错误。我读错了吗?
此外,我正在使用Visual Studio 2005,并且我读到Service Pack 1运行时不向后兼容。这是否意味着没有SP1构建的应用程序将无法在具有SP1 dll的计算机上运行,即使它们具有相同的名称(例如msvcr80.dll)?
答案 0 :(得分: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
关于你的上一个问题,是的,目标机器需要正确版本的运行时DLL才能工作,但是通过将它们部署为私有程序集,你可以保证。
另一个好处是,非管理员用户可以安装您的应用程序(不是安装到Program Files,而是安装在其他地方) - 他们不需要将文件写入WinSxS区域的权限。
答案 1 :(得分:12)
你唯一一次得到运行时的多个副本就是你将一个库静态链接到一个DLL中 - 每个DLL都会得到一个副本,exe也是如此。如果它们是所有静态库而不是DLL,它们将全部链接在一起,并且所有库将共享相同的运行时。
这是链接器的工作。
答案 2 :(得分:2)
...静态地做...修复DLL Hell的尝试还没有那么好......只需用静态链接为你的安装添加额外的200k。
答案 3 :(得分:1)
静态库不需要静态链接到其他静态库。您只需要链接主项目中的所有静态库。这样编译器就不会抱怨多个符号。