不,您不能将调试和发布运行时库与 Visual Studio 2017 混合使用。它们与 ABI 不兼容。
在 C++ 运行时中有用于调试检查的额外检查和成员变量,并且内存分配例程会在调试模式下增加额外的空间和检查。
示例代码取自<xmemory0>
( _Adjust_manually_vector_aligned
)
// Extra paranoia on aligned allocation/deallocation; ensure _Ptr_container is
// in range [_Min_back_shift, _Non_user_size]
#ifdef _DEBUG
constexpr uintptr_t _Min_back_shift = 2 * sizeof(void *);
#else /* ^^^ _DEBUG ^^^ // vvv !_DEBUG vvv */
constexpr uintptr_t _Min_back_shift = sizeof(void *);
#endif /* _DEBUG */
const uintptr_t _Back_shift = reinterpret_cast<uintptr_t>(_Ptr) - _Ptr_container;
_STL_VERIFY(_Back_shift >= _Min_back_shift && _Back_shift <= _Non_user_size, "invalid argument");
这里_DEBUG
函数的变体分配了额外2 * sizeof(void*)
的检查,而发布变体只使用sizeof(void*)
.
从这里很明显,由发布变体创建并由调试变体使用的指针(反之亦然)会触发各种混淆和错误检查。
因此,链接器错误可以防止这种情况发生。
也就是说,可以在特定情况下混合使用它们,尽管我不建议这样做。
您基本上必须创建两个分区,它们具有非常紧密和狭窄的界面。您必须确保除了POD 或完全不透明的数据类型之外没有任何类型的数据在“分区”之间传输。此外,您不能将调试库和发布库(因为 ABI 和符号冲突)静态链接到同一个二进制文件。
因此,您可以在“调试”例程中创建一个std::string
,但不允许将其传递给“发布”例程。但是你可以将'std::string::c_str()'返回值传递给'Release'例程,因为那只是一个指向char的指针。
为此,您可以将所有“发布”二进制文件放在一个 DLL 中,并将此 DLL 与静态“发布”运行时静态链接,并将所有“调试”二进制文件放在另一个 DLL(或 EXE)中,并将其与“调试”运行时静态链接. 这样,运行时就完全隐藏在它们各自的 DLL 中,并且对外界不可见。
(可以将一个或多个 DLL 与静态运行时链接,将其他 DLL 与动态运行时链接。但同样,我不推荐它)。
基本上,当您在 Windows 下运行“调试”应用程序时,就会发生这种情况。您不需要“调试”窗口来运行“调试”应用程序。您的“调试”应用程序在使用自己的“发布”运行时的“发布”Windows 上运行良好。只是 Windows 使用的“发布”运行时完全隐藏在您的“调试”发布时间之外。