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

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

I'm using Visual C++ 2008 SP1. I have an app that is compiled in debug mode, but links against a library in release mode.

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

I'm getting a crash at the start-up of the application. To make the problem smaller, I created a simple solution with 2 projects:

  • lib_release(生成 .lib,处于发布模式)
  • exec_using_lib_release(生成 .exe,处于调试模式)

lib_release"项目很简单,可以有一个简单的类:

The 'lib_release' project is simple enough to have a simple class:

//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"项目很简单:

The 'exec_using_lib_release' project is simple like this:

//main.cpp
#include "Foo.h"
int main() {
   Foo foo;
   foo.doSomething();
   return 0;
}

它崩溃了,这与 您如何针对发布构建的库 (MSVCRT.lib) 构建调试 .exe (MSVCRTD.lib)?,但他的回答不适用于我.

And it crashes, it's the same problem reported by How do you build a debug .exe (MSVCRTD.lib) against a release built lib (MSVCRT.lib)?, but his answer didn't work for me.

我收到相同的链接器警告,我尝试了相同的步骤,但没有一个成功.我有什么遗漏吗?

I get the same linker warnings, I tried the same steps, but none worked. Is there something I'm missing?

在 lib_release(在发布模式下创建库)上,我使用 多线程 (/MT),而在 exec_using_lib_release,我正在使用 多线程调试 (/MTd).我认为这是预期的方式,因为我希望在没有调试信息的情况下创建 .lib.我在 MSDN 运行时库,这些是静态链接 CRT 的设置.

On the lib_release (that creates a library in release mode), I'm using Multi Threaded (/MT), and at the exec_using_lib_release, I'm using Multi Threaded Debug (/MTd). I think this is the expected way of doing it, since I want the .lib to be created without debug info. I read the document at MSDN Runtime library and those are the settings of linking against the CRT in a static way.

我也没有通用语言运行时支持".

I don't have 'Common Language Runtime Support' either.

推荐答案

你没有必须为发布和调试模块使用相同的运行时(但它有帮助),只要你遵循非常具体的规则:永远不要混合和匹配访问使用每个运行时分配的内存.

You don't have to use the same runtimes for release and debug modules (but it helps), as long as you follow very specific rules: never mix and ,match accessing the memory allocated using each runtime.

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

To put this more simply, if you have a routine in a dll that allocates some memory and returns it to the caller, the caller must never free it - you must create a function in the original dll that frees the memory. That way you're safe from runtime mismatches.

如果您认为 Windows dll 仅构建发布(除非您有 Windows 的调试版本),但您在调试应用程序中使用它们,您会发现这很重要.

If you consider that the Windows dlls are built release only (unless you have the debug version of Windows), yet you use them from your debug applications, you'll see how this matters.

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

Your problem now is that you're using a static library, there is no dll boundary anymore, and the calls in the lib are compiled using the static version of the C runtime. If your exe uses the dynamic dll version of the runtime, you'll find that the linker is using that one instead of the one your static lib used... and you'll get crashes.

因此,您可以将您的库重新构建为 dll;或者您可以确保它们都使用相同的 CRT 库;或者您可以确保它们都使用相同类型的 CRT - 即 dll 版本或静态版本,同时保持调试/发布差异.

So, you could rebuild your lib as a dll; or you could make sure they both use the same CRT library; or you could make sure they both use the same type of CRT - ie the dll version or the static version, whilst keeping debug/release differences.

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

At least, I think this is your problem - what are the 'code generation, runtime library' settings?

相关文章