vector作为参数传递到dll问题
?最近的一個項目中遇到了調(diào)用別人的sdk接口(dll庫)而傳給我的是一個vector指針,用完之后還要我來刪除的情況。這個過程中首先就是在我的exe中將其vector指針轉(zhuǎn)為相應指針再獲取vector中相應的數(shù)據(jù)問題,始終都獲得不了正確的數(shù)據(jù),要么就是一些非法的數(shù)據(jù);另一個問題就是delete這個指針時候會產(chǎn)生相應異常(針對這個問題的思考:如果EXE和DLL都鏈接到DLL的C/C++運行期庫,那么代碼將能夠很好地運行.但是,如果兩個模塊中的一個或者兩個鏈接到靜態(tài)C/C++運行期庫,那delete的操作就會失敗.)。這叫一個折騰的糾結(jié)啊。搜羅了一些網(wǎng)絡資料以備以后的參考學習:
(1)對于STL,在DLL中使用的時候,往往存在這些問題,在網(wǎng)絡上搜集了下,這些都是要平時使用STL的時候注意的。
引用http://www.hellocpp.net/Articles/Article/714.aspx
template? 是個好東西啊 . 經(jīng)典的 stl . 強悍的boost. 還有我自己寫的那個 ------- 該死的 ------- 資源管理器.dynamic link也是個好東西啊. 在windows下叫dll, 在unix下叫so (share object) . 它能省下很多重新發(fā)布軟件帶來的麻煩.但是當template? 遭遇到dynamic link 時候, 很多時候卻是一場惡夢.現(xiàn)在來說說一部分我已經(jīng)碰到過的問題. 問題主要集中在內(nèi)存分配上. 1>?????? 拿STL來說, 自己寫模板的時候,很難免就用到stl. stl的代碼都在頭文件里.? 那么表示著內(nèi)存分配的代碼.只有包含了它的cpp 編譯的時候才會被決定是使用什么樣的內(nèi)存分配代碼. 考慮一下: 當你聲明了一個vector<> . 并把這個vector<>交給一個 dll里的代碼來用. 用完后, 在你的程序里被釋放了.??? 那么如果你 在dll里往vector里insert了一些東西. 那么這個時候insert 發(fā)生的內(nèi)存分配的代碼是屬于dll的. 你不知道這個dll的內(nèi)存分配是什么. 是分配在哪里的.? 而這個時候.釋放那促的動作卻不在dll里.....同時. 你甚至無法保證編譯dll的那個家伙使用的stl版本和你是完全一樣的..>????? 如此說來, 程序crash掉是天經(jīng)地義的....??????? 對策:?千萬別別把你的stl 容器,模板容器在 dll 間傳來傳去 .? 記住string也是.... 2>?????? 你在dll的某個類里聲明了一個vector之類的容器.? 而沒有顯式的寫這個類的構造和析構函數(shù). 那么問題又來了.???? 你這個類肯定有操作這vector的函數(shù). 那么這些函數(shù)會讓vecoter<>生成代碼. 這些代碼在這個dll里都是一致的. 但是別忘了.你沒有寫析構函數(shù)...... 如果這個時候, 別人在外面聲明了一個這樣的類.然后調(diào)用這個類的函數(shù)操作了這個vector( 當然使用者并不知道什么時候操作了vector) .? 它用完了這個類以后. 類被釋放掉了. 編譯器很負責的為它生成了一份析構函數(shù)的代碼...... 聽好了.這份代碼并不是在 dll里 ... . 事情于是又和1>里的一樣了.... crash ......(可能還會伴隨著迷茫.....)???? 對策:?記得dll里每個類,哪怕式構造析構函數(shù)式空的. 也要寫到cpp里去. 什么都不寫也式很糟糕的.....同時,更要把任何和內(nèi)存操作有關的函數(shù)寫到 .cpp 里... 3>???? 以上兩個問題似乎都是比較容易的-----只要把代碼都寫到cpp里去, 不要用stl容器傳來傳去就可以了.?? 那么第三個問題就要麻煩的多.?? 如果你自己寫了一個模板, 這個模板用了stl 容器..........?? 這個時候你該怎么辦呢? 顯然你無法把和內(nèi)存分配相關的函數(shù)都寫到.cpp里去 . template的代碼都必須放到header file里.....?? 對策:? 解決這個問題的基本做法是做一個stl 內(nèi)存分配器 , 強制把這個模板里和內(nèi)存分配相關的放到一個.cpp里去.這個時候編譯這個cpp就會把內(nèi)存分配代碼固定在一個地方: 要么是dll. 要么是exe里...?模板+動態(tài)鏈接庫的使用問題還很多. 要千萬留心這個陷阱遍地的東西啊
另外,對於這種問題的解決辦法,下面3種可行辦法: 1. 傳遞vector指針 2. 傳遞const vector 3. 儘量不使用stl作為dll間的傳遞參數(shù),使用指針會更好點
究其原因:是因為vector在exe和dll之間傳遞的時候,由于在dll內(nèi)可能對vector插入數(shù)據(jù),而這段內(nèi)存是在dll里面分配的,exe無法知道如何釋放內(nèi)存,從而導致問題。而改成const類型后,編譯器便知道dll里不會改變vector,從而不會出錯。或者可以說這是"cross-DLL problem."(This problem crops up when an object is created using new in one dynamically linked library (DLL) but is deleted in a different DLL)的一種吧。
(2)?從一個可執(zhí)行程序中輸出模板實例,在另一個可執(zhí)行程序中引入此實例。例如:MyLibrary.DLL將vector <MyClass> 指針回傳給MyProgram.EXE中的一個函數(shù),需要在MyLibrary.DLL中輸出MyClass類和vector <MyClass> 。在MyProgram.EXE中引入它們后。就可以得到MyLibrary.DLL中靜態(tài)數(shù)據(jù)成員的一份Copy了。
這個是解決我這個問題的挺不錯的方法,但是并為給予采納和驗證。畢竟為了保險起見最終還是選擇了數(shù)組傳遞數(shù)據(jù),但是還是要給予的原則是誰創(chuàng)建誰釋放。否則還是會出問題我這里即便是調(diào)用delete[ ]objArray;這里的delete的并不知道要刪除多大的內(nèi)存,而這個要刪除多大的內(nèi)存信息是在dll中保存著的,那個dll中的delete才知道。DLL中分配的內(nèi)存DLL要負責釋放!(一個模塊分配的內(nèi)存要在同一個模塊中釋放!)
?
總結(jié)
以上是生活随笔為你收集整理的vector作为参数传递到dll问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: __declspec(selectany
- 下一篇: 木马捆绑器设计思路和源码