混合调试和发布库/二进制 - 不好的做法?

M W*_*M W 24 c++ visual-studio-2010 visual-studio

在调试二进制文件中使用第三方库的发布版本是不好的做法吗?

我正在使用第三方库并编译了一个发行版.lib库.我的exe是在调试模式开发中.然后我得到了:

error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in test1.obj
Run Code Online (Sandbox Code Playgroud)

经过一些谷歌搜索,我发现这是因为我试图将发布与调试混合,我应该在调试模式下编译库,或者与_ITERATOR_DEBUG_LEVEL宏混淆.但我很好奇,如果这是推荐的方式和原因.我需要编译并保留我打算使用的每个第三方库的发布和调试二进制文件的记录,这很麻烦,这很快就会很多,而无意调试这些代码.

tin*_*man 32

混合调试和发布代码是不好的做法.问题是不同的版本可能依赖于C++运行时库的不同基本部分,例如如何分配内存,迭代器之类的结构可能不同,可以生成额外的代码来执行操作(例如,检查迭代器).

它与混合使用任何其他不同设置构建的库文件相同.想象一下,头文件包含应用程序和库使用的结构的情况.该库是通过将结构打包和对齐设置为一个值并使用另一个值构建的应用程序构建的.无法保证将结构从应用程序传递到库中将起作用,因为它们的大小和成员位置可能不同.

是否可以将第三方库构建为DLL?假设任何函数的接口更干净,并且不尝试传递任何STL对象,您将能够将调试应用程序与版本DLL混合而不会出现问题.

  • @JDługoszstd:: string在运行时之间显式不兼容.一个有趣的练习是创建一个只有函数`__declspec(dllexport)std :: string make_string()`的DLL,在Debug中构建,然后构建一个Release可执行文件,链接并调用该函数.当我尝试`std :: cout`返回的字符串时,导致的崩溃非常引人注目.这是使用VS2013,但它确实是VS2010的问题,我也期待其他版本.[这里](https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/)来自马口的一点信息. (3认同)
  • 不过,在 Linux 上,当您使用包管理器时,您会获得仅针对优化配置的预构建版本的库。似乎只有 Windows 具有这种分离的调试与发布概念,这使得维护预构建的依赖关系成为后方的巨大痛苦。在 VS2010 之前,将发布(优化)库与调试可执行文件链接起来总是完美的。ABI 兼容性不应在配置之间发生变化。 (2认同)

And*_*SFT 11

混合调试和发布库/二进制文件是很好且非常有用的实践。

调试大型解决方案(例如 100 多个项目)通常速度不快,甚至根本不可能(例如,并非所有项目都可以在调试中构建)。以前的评论员写道,调试/发布二进制文件可能有不同的对齐方式或其他人员。这不是真的。调试和发布二进制文件中的所有链接参数都相同,因为它们依赖于相同的体系结构。

您必须从所选项目中删除所有优化 (/Od)。然后分配一个发布的 c++ 运行时。

问题出现是因为您在项目中定义了 _DEBUG。从定义(项目->属性->预处理器->预处理器定义)中删除宏。

如果宏不在预处理器定义中,则必须将其添加到“UndefinePreprocessorDefinitions”中。

  • 我完全同意。这是常见的做法(至少在 Linux 世界中)。你不想调试 3d 方库,而且基本上我不能没有源。 (4认同)

Luc*_*ore 7

它不编译的事实应该足以证明这是不好的做法.

关于维护单独的构建 - 您不需要这样做.这是以前适用于我的解决方法:

#ifdef _DEBUG
#define DEBUG_WAS_DEFINED
#undef _DEBUG
#endif

#include <culprit>

#ifdef DEBUG_WAS_DEFINED
#define _DEBUG
#endif
Run Code Online (Sandbox Code Playgroud)

如果这对您有用,请告诉我.