我使用的是 Visual C++ 2008 SP1。我有一个在 Debug模式下编译的应用程序,但在 Release模式下链接到一个库。
我在应用程序启动时遇到崩溃。为了使问题更小,我创建了一个包含 2 个项目的简单解决方案:
- lib_release(生成.lib,处于 Release模式)
- exec_using_lib_release(在 Debug模式下生成 .exe)
“lib_release”项目很简单,只需要一个简单的类:
//Foo.h
#include <vector>
class Foo {
std::vector<int> v;
public:
void doSomething();
};
//Foo.cpp
#include "Foo.h"
void Foo::doSomething() {}
“exec_using_lib_release”项目很简单,如下所示:
//main.cpp
#include "Foo.h"
int main() {
Foo foo;
foo.doSomething();
return 0;
}
它崩溃了,这与How do you build a debug .exe (MSVCRTD.lib) against a release built lib (MSVCRT.lib)?报告的问题相同,但他的回答对我不起作用。
我收到相同的链接器警告,我尝试了相同的步骤,但都没有奏效。有什么我想念的吗?
编辑:
在 lib_release(在 Release模式下创建库)上,我正在使用多线程 (/MT),在 exec_using_lib_release 上,我正在使用多线程调试 (/MTd)。我认为这是预期的做法,因为我希望在没有调试信息的情况下创建 .lib。我在 MSDN Runtime library 阅读了文档以上就是静态链接CRT的设置。
我也没有“公共(public)语言运行时支持”。
最佳答案
您不必必须对发布和调试模块使用相同的运行时(但这会有所帮助),只要您遵循非常具体的规则:永远不要混合和匹配访问分配的内存使用每个运行时。
更简单地说,如果您在 dll 中有一个例程分配一些内存并将其返回给调用者,则调用者绝不能释放它 - 您必须在原始 dll 中创建一个函数来释放内存。这样您就可以避免运行时不匹配。
如果您认为 Windows dll 只是构建版本(除非您有 Windows 的调试版本),但您在调试应用程序中使用它们,您就会明白这有多么重要。
您现在的问题是您正在使用静态库,不再有 dll 边界,并且库中的调用是使用 C 运行时的静态版本编译的。如果您的 exe 使用运行时的动态 dll 版本,您会发现链接器正在使用该版本而不是您的静态库使用的版本……您会遇到崩溃。
因此,您可以将您的库重建为一个 dll;或者您可以确保它们都使用相同的 CRT 库;或者您可以确保它们都使用相同类型的 CRT - 即 dll 版本或静态版本,同时保持调试/发布差异。
至少,我认为这是您的问题 - “代码生成、运行时库”设置是什么?
关于c++ - 在 Visual Studio 中链接到版本中的库和调试中的 .exe 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1227653/