链接库中的库和.exe在Visual Studio中的调试崩溃

Edi*_*enz 6 c++ linker visual-studio-2008 visual-studio

我正在使用Visual C++ 2008 SP1.我有一个在调试模式下编译的应用程序,但在发布模式下链接到库.

我在启动应用程序时遇到了崩溃.为了缩小问题,我创建了一个包含2个项目的简单解决方案:

  • lib_release(在发布模式下生成.lib)
  • exec_using_lib_release(在调试模式下生成.exe)

'lib_release'项目非常简单,只需要一个简单的类:

//Foo.h
#include <vector>
class Foo {
  std::vector<int> v;
  public:
  void doSomething();
};
//Foo.cpp
#include "Foo.h"
void Foo::doSomething() {}
Run Code Online (Sandbox Code Playgroud)

'exec_using_lib_release'项目很简单,如下所示:

//main.cpp
#include "Foo.h"
int main() {
   Foo foo;
   foo.doSomething();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

它崩溃,这是由如何针对发布版本的lib(MSVCRT.lib)构建调试.exe(MSVCRTD.lib)报告的相同问题,但他的回答对我不起作用.

我得到了相同的链接器警告,我尝试了相同的步骤,但没有一个工作.有什么我想念的吗?

编辑:

在lib_release(在发布模式下创建一个库),我正在使用Multi Threaded(/ MT),在exec_using_lib_release,我正在使用多线程调试(/ MTd).我认为这是实现它的预期方式,因为我希望在没有调试信息的情况下创建.lib.我在MSDN运行时库中阅读了该文档,这些是以静态方式链接CRT的设置.

我也没有"公共语言运行时支持".

gbj*_*anb 8

你不拥有你遵守非常具体的规则使用相同的运行时间进行发布和调试模块(但它可以帮助),只要:从不随意,搭配使用访问每个运行时分配的内存.

更简单地说,如果你在dll中有一个例程来分配一些内存并将它返回给调用者,那么调用者就不能释放它 - 你必须在原来的dll中创建一个释放内存的函数.这样你就可以避免运行时不匹配.

如果你认为Windows dll只是构建版本(除非你有Windows的调试版本),但你从调试应用程序中使用它们,你会看到这是多么重要.

您现在的问题是您正在使用静态库,不再有dll边界,并且使用C运行时的静态版本编译lib中的调用.如果你的exe使用动态dll版本的运行时,你会发现链接器正在使用那个,而不是你的静态库使用的那个......你会崩溃.

所以,你可以重建你的lib作为一个DLL; 或者你可以确保它们都使用相同的CRT库; 或者您可以确保它们都使用相同类型的CRT - 即dll版本或静态版本,同时保持调试/发布差异.

至少,我认为这是你的问题 - 什么是'代码生成,运行时库'设置?


KJA*_*olf 5

对于早期人们提到的发布和调试问题的混合,这些问题在错误的运行时库试图解除分配之前不会出现.我认为你遇到的是VS 2008默认启用了迭代器调试,因此你的lib和你的exe指的是std :: vector的不同实现.您需要将_HAS_ITERATOR_DEBUGGING = 0添加到预处理器设置中.然后,您将开始针对不同的运行时遇到不同堆的问题.在过去,我们有不同的规则和政策来避免这种情况,但现在我们只依赖于一致的构建环境 - 不要混用和匹配.