c++ - 在 Visual Studio 中链接到版本中的库和调试中的 .exe 崩溃

标签 c++ visual-studio visual-studio-2008 linker

我使用的是 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/

相关文章:

visual-studio-2010 - 如何在Windows资源管理器中从Visual Studio打开项目文件夹?

c# - 如何在 VS 2013 上导出/导入断点?

c# - Visual Studio 2022 连接服务的 Azure Key Vault 集成

visual-studio - 在Visual Studio 2008/2010中的代码中为位置添加书签的最佳方法是什么?

c++ - 变量未在此范围内声明?

c++ - 没有输入/输出的函数是过程吗?

c++ - 给定程序中的段错误

c++ - 为什么指定的初始化程序没有在 g++ 中实现

c++ - 项目仅在特定版本的 Visual Studio 中编译

c++ - CMFCToolBarComboBoxButton 中的 AddItem - 未显示新值