将静态库转换为DLL导致main之前的访问冲突

Converting static library to DLL causes access violation before main

我们在 VS2015 中有一个大型解决方案,其中包含两个库和大量 win32 项目,用于测试我们的应用程序。我们的项目及其依赖如下:

这些库最初是静态的,但我们正在将它们转换为 DLL 以加快链接速度。我用 __declspec(dllexport) 装饰器修改了我们的应用程序代码,并成功地将我们的应用程序编译并链接为 DLL。所有不使用 eventLibrary.lib 构建且 运行 成功的测试用例,其余测试用例崩溃,因为 eventLibrary.libappLibrary.dlltestCase.exe.[=30= 中静态链接]

我将 eventLibrary.lib 转换为一个 DLL,它与我们的 exe 建立并链接,但在它们到达 main 之前就崩溃了。我正在使用 def 文件而不是修改库源。如果我从 testCase.exe 中删除 eventLibrary.dll 依赖项并从 appLibrary.dll 中导出其符号,则会发生完全相同的崩溃。

崩溃发生在重载的 << 运算符内的 ostream 中。传入的 stringstream(下面的参数 _Ostr)与使用静态库构建时相同。我得到一个 0xC0000005: Access violation executing location 0x0D20E4E9,这似乎是由调用 width 方法引起的:

template<class _Traits> inline
    basic_ostream<char, _Traits>& operator<<(
        basic_ostream<char, _Traits>& _Ostr,
        const char *_Val)
    {   // insert NTBS into char stream
    typedef char _Elem;
    typedef basic_ostream<_Elem, _Traits> _Myos;
    ios_base::iostate _State = ios_base::goodbit;
    streamsize _Count = (streamsize)_Traits::length(_Val);  // may overflow
    streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count
        ? 0 : _Ostr.width() - _Count; // <- Dies here

这发生在 Google 测试框架的全局初始化期间,它仍然是一个静态库。调用栈如下:

testCase.exe!testing::Message::operator<<(const char[7] & val) Line 131 testCase.exe!testing::internal::FlagToEnvVar(const char * flag) Line 1136 testCase.exe!testing::internal::BoolFromGTestEnv(const char * flag, bool default_value) Line 1195 testCase.exe!testing::`dynamic initializer for 'FLAGS_gtest_also_run_disabled_tests''() Line 202

动态链接我们的事件库是否以某种方式破坏了 testCase.exe 中的内存?这与拥有自己的堆的 DLL 有什么关系吗?我确保我们的 DLL 和 exe 在构建和链接时使用相同的运行时 (/MDd) 和相同的标志进行编译。

我通过将两个库源放在同一个 DLL 中解决了这个问题。我们的事件库实际上定义了用于导出到 DLL 的宏,并且我们通过将两者结合起来消除了任何依赖性问题。