我有一个烦人的问题,我可能能够以某种方式规避它,但另一方面,我更愿意了解它并了解到底发生了什么,因为看起来这些东西真的会留下来。
故事是这样的:我有一个简单的 OpenGL 应用程序,它运行良好:在编译、链接或运行它时从来都不是主要问题。现在我决定尝试将一些更密集的计算移到工作线程中,以便可能使 GUI 响应更快——当然是使用 Boost.Thread。
简而言之,如果我在 .cpp 文件的开头添加以下片段:
#include <boost/thread/thread.hpp>
void dummyThreadFun() { while (1); }
boost::thread p(dummyThreadFun);
,然后我在尝试启动调试版本时开始收到“此应用程序无法启动,因为未找到 MSVCP90.dll”。 ( Release模式工作正常。)
现在查看使用 Dependency Walker 的可执行文件,他也没有找到这个 DLL(我猜这是预期的),我可以看到我们正在寻找它以便能够调用以下函数:
?max@?$numeric_limits@K@std@@SAKXZ
?max@?$numeric_limits@_J@std@@SA_JXZ
?min@?$numeric_limits@K@std@@SAKXZ
?min@?$numeric_limits@_J@std@@SA_JXZ
接下来,我尝试转换
min
的每个实例和 max
改用宏,但可能找不到对它们的所有引用,因为这没有帮助。 (我正在使用一些我没有可用源代码的外部库。但即使我能做到这一点——我认为这不是正确的方法。)所以,我的问题——我猜——是:
我首先在 Visual Studio 2008 的一个非常普通的安装中安装了这个。然后尝试安装 Feature Pack 和 SP1,但它们也没有帮助。当然也尝试过多次Rebuild。
我正在为 Boost (v1.36.0) 使用预构建的二进制文件。这不是我第一次在这个项目中使用 Boost,但这可能是我第一次使用基于单独源的部件。
禁用增量链接无济于事。该程序是 OpenGL 的事实似乎也无关紧要——我在将相同的三行代码添加到一个简单的控制台程序中时遇到了类似的问题(但它在那里提示 MSVCR90.dll 和
_mkdir
,并且当我用 boost::create_directory
替换后者时,问题就消失了!!)。它实际上只是删除或添加那三行,分别使程序运行正常或根本不运行。我不能说我理解 Side-by-Side(甚至不知道这是否相关,但这就是我现在的假设),老实说,我也不是 super 感兴趣——只要我能构建、调试和部署我的应用程序...
编辑 1:在尝试构建一个无论如何都会重现问题的精简示例时,我发现该问题与 the Spread Toolkit 有关。 ,使用它是我所有遇到此问题的程序的共同因素。 (但是,在开始链接 Boost 内容之前,我从未有过这个。)
我现在想出了一个最小的程序,可以让我重现这个问题。它由两个编译单元组成,A.cpp 和 B.cpp。
A.cpp:
#include "sp.h"
int main(int argc, char* argv[])
{
mailbox mbox = -1;
SP_join(mbox, "foo");
return 0;
}
B.cpp:
#include <boost/filesystem.hpp>
一些观察:
SP_join
A.cpp,问题就解决了。 (在场景 2 和 3 中,程序在调用
SP_join
时崩溃,但这只是因为邮箱无效......这与手头的问题无关。)此外,Spread 的核心库已链接,这肯定是我的问题 #1 的答案的一部分,因为我的系统中没有该库的调试版本。
目前,我正在尝试提出一些可以在另一个环境中重现该问题的方法。 (尽管如果它真的可以在我的场所外重复,我会感到非常惊讶......)
编辑 2:好的,所以 here我们现在有一个包,我可以使用它在 WinXP32 + VS2008 + Boost 1.36.0(仍然是 pre-built binaries from BoostPro Computing )的几乎普通安装上重现该问题。
罪魁祸首肯定是Spread lib,我的构建以某种方式需要MSVC 6的STLPort相当陈旧的版本!尽管如此,我仍然觉得这些症状比较有趣。此外,很高兴听到您是否可以真正重现该问题 - 包括上面的场景 1-3。包裹很小,它应该包含所有必要的部分。
事实证明,这个问题实际上与 Boost.Thread 没有任何关系,因为这个例子现在使用 Boost 文件系统库。此外,它现在提示 MSVCR90.dll,而不是以前的 P。
最佳答案
Boost.Thread 有很多可能的构建组合,以尝试满足 MSVC 可能的链接场景中的所有差异。首先,您可以静态链接到 Boost.Thread,或者链接到单独 DLL 中的 Boost.Thread。然后,您可以链接到 MSVC 运行时的 DLL 版本或静态库运行时。最后,您可以链接到调试运行时或发布运行时。
Boost.Thread 头文件尝试使用编译器生成的预定义宏自动检测构建场景。为了链接到使用调试运行时的版本,您需要有 _DEBUG
定义。这是由/MD 和/MDd 编译器开关自动定义的,因此应该没问题,但您的问题描述另有说明。
你从哪里得到预构建的二进制文件?您是在项目设置中明确选择一个库,还是让自动链接机制选择适当的 .lib 文件?
关于c++ - 添加 Boost 使调试构建依赖于 "non-D"MSVC 运行时 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/222778/