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

发布于 2024-07-17 06:07:09 字数 488 浏览 7 评论 0原文

我读过双方关于在 Visual Studio 项目中应该静态还是动态链接到 C 运行时库的争论,但我仍然不完全确定该怎么想。

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

我想避免“DLL Hell”,但担心在运行时的多个副本中静态链接可能会出现潜在的错误。 我读错了吗?

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

I have read arguments on both sides about whether one should link to the C runtime library statically or dynamically in Visual Studio projects, and I'm still not entirely sure what to think.

My project pulls in some third-party libraries (Python, HDF5, Trilinos, and Microsoft MPI), each of which has to be built with the same runtime library as my final executable (otherwise they cannot be linked together). When linking statically, each of these libraries will contain a copy of the C runtime. I read that this is liable to cause issues because the final executable will contain multiple copies of the runtime, none of which can interact with each other. But wouldn't the linker complain if the same symbols were multiply defined?

I would like to avoid "DLL Hell" but am worried about insidious errors that could arise from statically linking in multiple copies of the runtime. Am I reading things wrong?

Also, I'm using Visual Studio 2005 and I read that the Service Pack 1 runtime is not backwards-compatible. Does this mean that an app built without SP1 will not run on a machine that has the SP1 dlls, even if they have the same name (e.g. msvcr80.dll)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

π浅易 2024-07-24 06:07:09

静态链接会使所有 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 区域的权限。

Linking statically will bloat all your EXEs and DLLs, and can cause crashes (eg. if code in one DLL calls free() with a pointer allocated by malloc() in a different DLL).

You can get the best of both worlds by linking dynamically and deploying the runtime DLLs as private assemblies. This simply means putting a copy of a specially-named directory containing the runtime DLLs and their manifests next to your executable.

See the section "Deploying Visual C++ library DLLs as private assemblies" at http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx for details, but basically your application looks like this:

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

As to your last question, yes, the target machine needs the correct versions of the runtime DLLs to work, but by deploying them as private assemblies, you guarantee that.

Another benefit is that non-admin users can install your app (not into Program Files, but elsewhere) - they don't need permission to write files into the WinSxS area.

早乙女 2024-07-24 06:07:09

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

这就是链接器的工作。

The only time you'll get multiple copies of the runtime is when you statically link a library into a DLL - each DLL will get a copy, and so will the exe. If they're all static libraries and not DLLs, they'll all link together and all of your libraries will share the same runtime.

That's the linker's job.

梦里°也失望 2024-07-24 06:07:09

静态库不需要静态链接到其他静态库。 您只需链接主项目中的所有静态库即可。 这样编译器就不会抱怨多个符号。

Static libraries don´t need to be statically linked to other static libraries. You only need to link all static libraries in your main project. That way the compiler will not complain about multiple symbols.

地狱即天堂 2024-07-24 06:07:09

...静态地执行...尝试修复 DLL Hell 效果并不好...只需使用静态链接向您的安装添加额外的 200k。

... Do it statically... attempts to fix DLL Hell haven't worked out that well... just add an extra 200k to your installation with the static linkage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文