我在另一台计算机上构建和运行项目时遇到了一些奇怪的问题。这是一个并排的错误。通常原因是机器上没有安装c ++可再发行组件等。但是在这种情况下,项目是在该机器上编译的。安装了MSVC ++ 2005,运行时应该在那里(无论如何我再次安装了运行时)。为什么链接器引用了机器上不可用的运行时库?
我正在动态链接到运行时库。
有关如何调试此问题的任何想法?
感谢。
修改的
我不想开始另一篇文章,因为它是相关的。由于这个DLL版本一团糟,这是静态链接到运行时的一个很好的理由吗?我会避免所有这些问题吗?我认为动态链接到运行时没有任何优势。我的印象是,使用DLL运行时,您可以获得使用新DLL进行更新/错误修复的好处。但是由于SxS和清单,它确保它加载DLL的特定版本(旧版本)?那么动态运行时到底有什么意义呢?可能节省了几kb的空间,因为您没有在所有依赖库中嵌入重用函数。但是比较一下你的应用程序的成本将无法运行,因为从机器中删除了一些古老的运行时版本,是否值得呢?
再次感谢。仍在跟踪原始问题,可能需要重新编译我正在使用的每个库。
答案 0 :(得分:5)
sxstrace
将告诉您与SxS有关的具体信息。它将显示搜索的dll以及它们如何映射到实际版本。
现在,加载哪个运行时来自项目中包含的清单文件。看看你提到的那个,它看起来像是来自Visual2005的那个,没有服务包。 SP1将crt更改为8.0.50727.762
Some details on sxstrace on vista and XP
好吧,既然你在问题中添加了一个问题,那么让我回答一下我的答案: SxS不一定会加载您在清单中指定的版本。 SxS系统跟踪对特定版本所做的安全修复,例如并且即使您要求特定版本,也会更改它加载的版本。
也就是说,如果你的程序使用DLL,并且你想在它们之间共享C对象(例如malloc'ed内存),那么你唯一的选择是CRT DLL。这实际上取决于你的约束条件。
答案 1 :(得分:1)
不是问题的答案,而是这个问题的答案:
为什么链接器引用机器上不可用的运行时库?
链接器不需要实际的运行时库来链接。它只需要(通常)链接时的.lib文件。当操作系统在运行时找到dll时,.lib文件告诉链接器运行时库将提供什么(如在导出的符号中)。
在这样的情况下,Dependency Walker可以帮助调试问题。
编辑:跟进新问题。静态链接确实解决了这些问题,但它也引入了一些新问题。您可以在dll之间共享动态分配的对象 - 但是,分配该对象的dll必须是要解除分配的对象。同样必须管理对象上分配/重新分配/解除分配成员数据/对象的任何方法,以避免堆损坏。非内联引用计数/共享指针将很有帮助。或者,shared mem allocators也可以提供帮助。
答案 2 :(得分:1)
当您在另一台计算机上编译的第三方库或目标文件进行编译时,可能会发生这种情况,并且会在发生问题的计算机上进行复制。
尝试在您的计算机上找到此类二进制文件,并在该计算机上重新编译它们。
答案 3 :(得分:0)
这是一个possibly related forum post。不确定这是否是问题,但似乎值得检查。
摘要是MS通过自动更新更新了VS 2005开发人员计算机上的ATL,CRT,MFC和其他一些库。
在没有安装VS2005的计算机上,他们只通过自动更新更新了ATL,导致SxS错误。
您可以在开发计算机上卸载更新,也可以在您尝试运行的计算机上手动升级运行时。有关post的详细信息。