将静态库转换为DLL会导致主

时间:2018-01-30 21:48:24

标签: c++ windows dll visual-studio-2015 googletest

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

  • 活动图书馆

    • winmm.dll(用于计时功能)
  • App Library

    • eventLibrary.lib(静态)
  • 测试用例

    • eventLibrary.lib(静态)
    • appLibrary.lib(静态)
    • gtestd.lib(静态,Google测试框架)

这些库最初是静态的,但我们正在将它们转换为DLL以便更快地进行链接。我已使用__declspec(dllexport)装饰器修改了我们的应用代码,并已成功编译并将我们的应用链接为DLL。所有未使用eventLibrary.lib构建并成功运行的测试用例,由于eventLibrary.libappLibrary.dlltestCase.exeeventLibrary.lib被静态链接,因此其余的测试版崩溃了。

我将main转换为DLL,它与我们的exes建立并链接,但在到达eventLibrary.dll之前崩溃。我使用def文件而不是修改库源。如果我从testCase.exe中删除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 方法引起的:

testCase.exe

这发生在Google Test框架中的全局变量初始化期间,该框架仍然是一个静态库。调用堆栈如下:

  

testCase.exe!testing :: Message :: operator&lt;&lt;(const char [7]&amp; val)第131行       testCase.exe!testing :: internal :: FlagToEnvVar(const char * flag)第1136行       testCase.exe!testing :: internal :: BoolFromGTestEnv(const char * flag,bool default_value)第1195行       testCase.exe!testing ::`动态初始化程序,用于&#39; FLAGS_gtest_also_run_disabled_tests&#39;&#39;()第202行

是否动态链接我们的事件库以某种方式破坏/MDd中的内存?这有没有与拥有自己的堆的DLL有关?我确保在构建和链接时使用相同的运行时(<div class="Container"> <div class="HighlightContainer"> <div class="NodeTextHighlightContainer"> <span class="TreeItemSelected">Products</span> </div> <button class="ContainerSelectedMenu" type="button"></button> </div> </div> )和相同的标志编译我们的DLL和exes。

1 个答案:

答案 0 :(得分:0)

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