簡體   English   中英

將靜態庫轉換為DLL會導致在訪問main之前發生訪問沖突

[英]Converting static library to DLL causes access violation before main

在VS2015中,我們有一個大型解決方案,其中包含兩個庫和大量用於測試應用程序的win32項目。 我們的項目及其依賴項如下:

  • 活動庫

    • winmm.dll(用於計時功能)
  • 應用程式庫

    • eventLibrary.lib(靜態)
  • 測試用例

    • eventLibrary.lib(靜態)
    • appLibrary.lib(靜態)
    • gtestd.lib(靜態,Google Test框架)

這些庫最初是靜態的,但是我們將它們轉換為DLL,以實現更快的鏈接。 我已經使用__declspec(dllexport)裝飾器修改了我們的應用程序代碼,並成功地將我們的應用程序編譯和鏈接為DLL。 所有不使用eventLibrary.lib測試用例eventLibrary.lib構建並成功運行,其余的用例均崩潰,因為eventLibrary.libappLibrary.dlltestCase.exe中都是靜態鏈接的。

我將eventLibrary.lib轉換為DLL,該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 Test框架(仍是靜態庫)中的全局變量初始化期間發生的。 調用堆棧如下:

testCase.exe!testing :: Message :: operator <<(const char [7]&val)第131行testCase.exe!testing :: internal :: FlagToEnvVar(const char * flag)第1136行testCase.exe!testing ::內部的:: BoolFromGTestEnv(const char *標志,布爾默認值)1195行testCase.exe!

動態鏈接我們的事件庫會以某種方式破壞testCase.exe內存嗎? 這與擁有自己堆的DLL有什么關系嗎? 我確保在構建和鏈接時,使用相同的運行時( /MDd )和相同的標志來編譯我們的DLL和exe。

我通過將兩個庫源放在同一DLL中解決了該問題。 我們的事件庫實際上已經定義了用於導出到DLL的宏,並且我們通過將兩者結合在一起消除了任何依賴項問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM