[英]Converting static library to DLL causes access violation before main
在VS2015中,我們有一個大型解決方案,其中包含兩個庫和大量用於測試應用程序的win32項目。 我們的項目及其依賴項如下:
活動庫
應用程式庫
測試用例
這些庫最初是靜態的,但是我們將它們轉換為DLL,以實現更快的鏈接。 我已經使用__declspec(dllexport)
裝飾器修改了我們的應用程序代碼,並成功地將我們的應用程序編譯和鏈接為DLL。 所有不使用eventLibrary.lib
測試用例eventLibrary.lib
構建並成功運行,其余的用例均崩潰,因為eventLibrary.lib
在appLibrary.dll
和testCase.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.