1

我在另一台计算机上构建和运行项目时遇到了一些奇怪的问题。这是一个并排的错误。通常原因是机器上未安装 c++ 可再发行组件等。但是在这种情况下,项目是在该机器上编译的。安装了 MSVC++ 2005,运行时应该在那里(无论如何,我再次安装了运行时)。为什么链接器引用机器上不可用的运行时库?

我正在动态链接到运行时库。

关于如何调试此问题的任何想法?

谢谢。

编辑

我不想开始另一个帖子,因为它是相关的。由于这个 DLL 版本混乱,这是静态链接到运行时的好理由吗?我会避免所有这些问题吗?我看不到动态链接到运行时的任何优势。我的印象是,使用 DLL 运行时,您可以获得使用新 DLL 进行更新/错误修复的好处。但是,由于 SxS 和清单,它确保它无论如何都会加载 DLL 的特定版本(旧版本)?那么动态运行时到底有什么意义呢?可能节省了几 kb 的空间,因为您没有在所有依赖库中嵌入重用函数。但这与您的应用程序无法运行的成本相比,因为某些古老的运行时版本已从机器中删除,这不值得吗?

再次感谢。仍在追踪原始问题,并且可能必须重新编译我正在使用的每个库。

4

4 回答 4

5

sxstrace会告诉你关于 SxS 的确切情况。它将显示搜索的 dll 以及它们如何映射到实际版本。

现在,加载哪个运行时来自项目中包含的清单文件。查看您提到的那个,它看起来像 Visual2005 中的那个,没有服务包。SP1 将 crt 更改为 8.0.50727.762

vista 和 XP 上 sxstrace 的一些细节

好吧,既然您在问题中添加了一个问题,那么让我为我的答案添加一个答案:SxS 不一定会加载您在清单中指定的版本。SxS 系统会跟踪对特定版本所做的安全修复,例如,即使您要求特定版本,它也会更改它加载的版本。

也就是说,如果您的程序使用 DLL,并且您想在它们之间共享 C 对象(例如 malloc'ed 内存),那么您唯一的选择就是 CRT DLL。这真的取决于你的约束是什么。

于 2009-10-13T16:07:55.503 回答
1

不是问题的答案,而是这个问题的答案:

为什么链接器引用机器上不可用的运行时库?

链接器不需要实际的运行时库来链接。它只需要(通常)链接时的 .lib 文件。当操作系统在运行时定位 dll 时,.lib 文件告诉链接器运行时库将提供什么(如在导出的符号中)。

在这种情况下, Dependency Walker可以帮助调试问题。

编辑:跟进新问题。静态链接确实解决了这些问题,但它也引入了一些新问题。您可以在 dll 之间共享动态分配的对象 - 但是,分配该对象的任何一个 dll 都必须是释放它的那个。对象上分配/重新分配/解除分配成员数据/对象的任何方法都必须同样受到管理,以避免堆损坏。非内联引用计数/共享指针会有所帮助。或者,共享内存分配器也很有帮助。

于 2009-10-13T15:44:41.137 回答
1

当您沿着第三方库或目标文件编译时,可能会发生这种情况,您在另一台机器上编译并在发生问题的机器上复制。

尝试在您的机器上找到此类二进制文件,然后在该机器上重新编译它们。

于 2009-10-13T16:02:30.757 回答
0

这是一个可能相关的论坛帖子。不确定这是否是问题所在,但似乎值得检查。

总结是 MS 通过自动更新更新了 VS 2005 开发人员机器上的 ATL、CRT、MFC 和其他一些库。

在没有安装 VS2005 的机器上,他们只通过自动更新更新 ATL,导致 SxS 错误。

您可以在开发机器上卸载更新,或者在您尝试运行的机器上手动升级运行时。帖子上的详细信息。

于 2009-10-13T16:13:28.013 回答