一個STL物件的DLL邊界傳遞問題
c++, DLL, std::string, STL, crt
這裡有非常詳細的一篇[url=http://www.gamedev.net/topic/337108-passing-stdstring-over-dll-boundaries/]討論[/url]僅供參考
也有可能是一個[url=http://support.microsoft.com/kb/172396/en-us/]已知的微軟實現問題[/url]
最近在重構專案時遇到的一個問題:提取了原來專案中的一些公共方法到一個新的DLL,暴露的工具方法中多數以const std::string& 為引數。在除錯時發現當主程式(exe)呼叫DLL中的這些工具方法時傳入的string會發生莫名其妙的變化(不是encoding問題)。比如在主程式中的string的buffer地址為0x0118cd8,可是剛剛進入工具方法(const std::string&)這個string的內容就變了,而且buffer地址也發生了變化,根據觀察只有幾個位元組的偏移。開發環境為VC2008。
[size=large][b]排除過程[/b][/size]
首先檢查了C++的Runtime library,確定都是/MD,另外調整了兩個工程的其它編譯,連線選項到一致,問題依舊。最後在編譯命令列中(Command Line)發現了一個可疑點,_DEBUG預編譯項。可是我明明用的是/MD(Multithreaded DLL),不是/MDd(debug),為什麼會有_DEBUG呢?為了驗證猜測,使用“Undefine Preprocessor Definitions”取消了_DEBUG定義,問題解決!
其實問題的根源在於我這個除錯用的Build Configuration,是基於預設的Debug建立的,這樣,VS或預設為你加上_DEBUG定義,而我們這個專案原來的工程的debug環境都是基於Release配置建立的build configuration。其實不僅是string,STL中的很多型別(不敢說全部)都存在這樣的問題。
[size=large][b]總結[/b][/size]
1. 為了保證程式行為的一致性,DLL與主程式的runtime library最好完全一致,否則便可能引入各種連結和執行時錯誤。
2. DLL的介面方法好暴露C式的方法簽名,這樣一方面可以提高LIB的可用性,還能杜絕STL物件的這種問題。
3. 錯誤的排除可以從編譯器和連結器的的command line引數入手
4. 在為專案新增新的工程時尤其需要注意
這裡有非常詳細的一篇[url=http://www.gamedev.net/topic/337108-passing-stdstring-over-dll-boundaries/]討論[/url]僅供參考
也有可能是一個[url=http://support.microsoft.com/kb/172396/en-us/]已知的微軟實現問題[/url]
最近在重構專案時遇到的一個問題:提取了原來專案中的一些公共方法到一個新的DLL,暴露的工具方法中多數以const std::string& 為引數。在除錯時發現當主程式(exe)呼叫DLL中的這些工具方法時傳入的string會發生莫名其妙的變化(不是encoding問題)。比如在主程式中的string的buffer地址為0x0118cd8,可是剛剛進入工具方法(const std::string&)這個string的內容就變了,而且buffer地址也發生了變化,根據觀察只有幾個位元組的偏移。開發環境為VC2008。
[size=large][b]排除過程[/b][/size]
首先檢查了C++的Runtime library,確定都是/MD,另外調整了兩個工程的其它編譯,連線選項到一致,問題依舊。最後在編譯命令列中(Command Line)發現了一個可疑點,_DEBUG預編譯項。可是我明明用的是/MD(Multithreaded DLL),不是/MDd(debug),為什麼會有_DEBUG呢?為了驗證猜測,使用“Undefine Preprocessor Definitions”取消了_DEBUG定義,問題解決!
其實問題的根源在於我這個除錯用的Build Configuration,是基於預設的Debug建立的,這樣,VS或預設為你加上_DEBUG定義,而我們這個專案原來的工程的debug環境都是基於Release配置建立的build configuration。其實不僅是string,STL中的很多型別(不敢說全部)都存在這樣的問題。
[size=large][b]總結[/b][/size]
1. 為了保證程式行為的一致性,DLL與主程式的runtime library最好完全一致,否則便可能引入各種連結和執行時錯誤。
2. DLL的介面方法好暴露C式的方法簽名,這樣一方面可以提高LIB的可用性,還能杜絕STL物件的這種問題。
3. 錯誤的排除可以從編譯器和連結器的的command line引數入手
4. 在為專案新增新的工程時尤其需要注意
相關文章
- 請教一個rmi分佈運算或者傳遞物件的問題!物件
- 一個關於值傳遞呼叫的問題
- 請教一個JSF引數傳遞的問題JS
- 請教一個在Tiles中引數傳遞的問題
- 有趣的CSS題目(7):消失的邊界線問題CSS
- 一個建立物件的問題物件
- 用C#呼叫C++DLL時的字串指標引數傳遞問題C#字串指標
- 問一個動態物件的問題物件
- C++進階:STL演算法9--邊界C++演算法
- 物件鎖:傳遞物件鎖物件
- Vector儲存物件的一個問題物件
- 請教一個傳遞引數的時候中文顯示亂碼的問題。
- css刪除最後一個邊界線CSS
- Swoole - TCP流資料邊界問題解決方案TCP
- 使用Intent傳遞物件Intent物件
- PHP中物件的引用傳遞PHP物件
- 請教一個物件設計的問題物件
- hibernate物件對映的一個問題。物件
- php傳遞json給jquery的問題PHPJSONjQuery
- 在平時開發的時候,你有考慮過邊界問題嗎?說說你對邊界的理解!
- freemarker+webwork+ebj2+Hibernate3開發物件傳遞問題Web物件
- 請教一個切片遞迴賦值的問題遞迴賦值
- 問一個透過物件序列化servlet給applet傳送影像的問題!!急!物件ServletAPP
- 一個物件多處引用的維護問題物件
- 引數傳遞中編碼問題(Get/Post 方式)(一)
- AXIS - 傳遞自定義物件物件
- 請教一個檔案上傳的問題
- 劃分微服務邊界的5個特徵微服務特徵
- Flutter實現一個邊讀邊處理邊傳送檔案的功能Flutter
- java值物件的傳輸問題請教Java物件
- 技術的邊界
- 《超越邊界》
- 解決CORS跨域不能傳遞cookies的問題CORS跨域Cookie
- Python-單繼承中值傳遞的問題Python繼承
- 不同資料庫間傳遞資料的問題資料庫
- String型別函式傳遞問題型別函式
- 問題多多的STL實現 (轉)
- Android Fragment 間物件傳遞AndroidFragment物件