有關 exe 呼叫 dll 記憶體管理的問題 |
答題得分者是:aftcast
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
請問各位,
我發現一個很大的問題, 這個問題其實困擾我五六年, 之前我的程式都是一支主程式exe 再呼叫 dll 檔, 例如 a.exe call b.dll 但最近可能因為程式不斷的發展, 在某些操作上, 由 a.exe call b.dll\, 然後結束 b.dll 後, 會造成 Access Error 的錯誤, 我一在查這個問題, 今天我測試了一個狀況, 而進一步解決不會再出現問題, 我發現, 在 dll 會引發錯誤時, 我的 dll 檔大小約在 3800k 以上, 我把程式縮小到 3500k以下, A.EXE CALL B.DLL (CLOSE B.DLL), 就不會引發 Access 問題 我的操作環境 Delphi5 Windows 2003 或 Windows XP 皆會引發當機 在 Win7 上則可以順利執行, 不會錯誤 所以我猜, 可能是 x86的記憶體管理模組是否無法掌握太大K數的程式, 而在 DLL 的開發設定中, 只有一組 Memory Size 可以設定 Image Base位址可以指定, 不知各位對於這一塊, 有沒有什麼經驗可以解決? |
jcjroc
高階會員 發表:21 回覆:279 積分:115 註冊:2002-09-18 發送簡訊給我 |
|
leveon
資深會員 發表:30 回覆:389 積分:303 註冊:2012-02-12 發送簡訊給我 |
大概是 use 了sharemem 用了string當回傳參數
如果DLL給VB VC用 大概也會出錯 建議傳遞參數最好用"指標"傳 ===================引 用 P.D. 文 章=================== 請問各位, 我發現一個很大的問題, 這個問題其實困擾我五六年, 之前我的程式都是一支主程式exe 再呼叫 dll 檔, 例如 a.exe call b.dll 但最近可能因為程式不斷的發展, 在某些操作上, 由 a.exe call b.dll\, 然後結束 b.dll 後, 會造成 Access Error 的錯誤, 我一在查這個問題, 今天我測試了一個狀況, 而進一步解決不會再出現問題, 我發現, 在 dll 會引發錯誤時, 我的 dll 檔大小約在 3800k 以上, 我把程式縮小到 3500k以下, A.EXE CALL B.DLL (CLOSE B.DLL), 就不會引發 Access 問題 我的操作環境 Delphi5 Windows 2003 或 Windows XP 皆會引發當機 在 Win7 上則可以順利執行, 不會錯誤 所以我猜, 可能是 x86的記憶體管理模組是否無法掌握太大K數的程式, ---------------------------- 2G以上再來考慮檔案太大的問題 而在 DLL 的開發設定中, 只有一組 Memory Size 可以設定 Image Base位址可以指定, 不知各位對於這一塊, 有沒有什麼經驗可以解決? --------------------------------------------------------------------------- image base 你可以Google "相對虛擬位址" "Relative Virual Address" "PE檔"可以得到更多資料 不過你的問題應該跟這個設定無關 |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
以上兩位所指點的, 其實我都一再的檢查及測試過, 因為我也知道使用ShareMemory 或者 FastShareMem, ShareMemRep 管理記憶體都強調參數不要用Stirng傳, 而必須改用 pChar 或 ShortString 定義, 而我的 dll 也刻意不傳遞參數,
另外, 我也清楚發生 Access Error 多半是物件未釋放或者釋放不存在物件等等問題, 但仔細查證程式, 並無這方面的問題, 每一個我自建的物件都有被釋放, 而整支程式由原來 5M 多降至 3M多就不會引發當機(降M的部份是引用圖片拿掉), 或許各位會認為是圖片的問題, 但我把圖片(jpg)的像素及解析降低, 一樣放進來達到 3M 容量的情況下, 還是不會引發, 所以可以確認不是有沒有加圖片進來的問題, 因為也就是困擾我的部份 |
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
leveon
資深會員 發表:30 回覆:389 積分:303 註冊:2012-02-12 發送簡訊給我 |
===================引 用 P.D. 文 章=================== 以上兩位所指點的, 其實我都一再的檢查及測試過, 因為我也知道使用ShareMemory 或者 FastShareMem, ShareMemRep 管理記憶體都強調參數不要用Stirng傳, 而必須改用 pChar 或 ShortString 定義, 而我的 dll 也刻意不傳遞參數, 這段聽起來怪怪的 應該是"為了傳string" 所以用了share fastshare Mem,如沒傳參數 應該"不需要"use sharemem 或其他3rd MM 一旦用了 程式都會變的不穩定 如果你有use 應該拿掉 另外, 我也清楚發生 Access Error 多半是物件未釋放或者釋放不存在物件等等問題, 但仔細查證程式, 並無這方面的問題, 每一個我自建的物件都有被釋放, 而整支程式由原來 5M 多降至 3M多就不會引發當機(降M的部份是引用圖片拿掉), 或許各位會認為是圖片的問題, 但我把圖片(jpg)的像素及解析降低, 一樣放進來達到 3M 容量的情況下, 還是不會引發, 所以可以確認不是有沒有加圖片進來的問題, 因為也就是困擾我的部份 引發當機的點 是指呼叫freelibrary 嗎 ,其實不把dll卸載掉 也不會怎樣 下次呼叫 還會快一點呢 |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
jcjroc
高階會員 發表:21 回覆:279 積分:115 註冊:2002-09-18 發送簡訊給我 |
還有寫入溢位的問題阿!!
看你的描述.....不release dll沒事,一release就出錯........應該是這事.. ===================引 用 P.D. 文 章=================== 以上兩位所指點的, 其實我都一再的檢查及測試過, 因為我也知道使用ShareMemory 或者 FastShareMem, ShareMemRep 管理記憶體都強調參數不要用Stirng傳, 而必須改用 pChar 或 ShortString 定義, 而我的 dll 也刻意不傳遞參數, 另外, 我也清楚發生 Access Error 多半是物件未釋放或者釋放不存在物件等等問題, 但仔細查證程式, 並無這方面的問題, 每一個我自建的物件都有被釋放, 而整支程式由原來 5M 多降至 3M多就不會引發當機(降M的部份是引用圖片拿掉), 或許各位會認為是圖片的問題, 但我把圖片(jpg)的像素及解析降低, 一樣放進來達到 3M 容量的情況下, 還是不會引發, 所以可以確認不是有沒有加圖片進來的問題, 因為也就是困擾我的部份 |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
我曾經有嘗試過BPL的寫法, 但因為我現在使用是DELPHI5版本, 不同版本BPL 都要重新編譯(XE2), 很麻煩
另外, 我的程式(DLL) 有很多共用的 PAS, 使用 BPL 要改一大堆, 因為相同的 FUNCTION 不能同時存在不同的BPL 而我所提的 EXE CALL DLL 這只是其中一支程式, 我一共有100支DLL檔, 雖然不是每一支都會當, 但只要K數在5M以上的, 當機率就很高, 但我確信不是中毒, 目前我還查不到任何可能引發的問題, 而提出溢位問題, 確實有這個可能性, 但也無法查出是那一部份引發溢位, 所以根本無法改起! ===================引 用 RootKit 文 章=================== 為何不將 DLL 改為 BPL方式 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
太忙,快速插花!
把dll的source code 加入主程式的project group裡,這樣不是可以debug到dll的錯誤嗎? (我用cb的做法來想,不確定delphi,但理當同理?!) ===================引 用 P.D. 文 章=================== 我曾經有嘗試過BPL的寫法, 但因為我現在使用是DELPHI5版本, 不同版本BPL 都要重新編譯(XE2), 很麻煩 另外, 我的程式(DLL) 有很多共用的 PAS, 使用 BPL 要改一大堆, 因為相同的 FUNCTION 不能同時存在不同的BPL 而我所提的 EXE CALL DLL 這只是其中一支程式, 我一共有100支DLL檔, 雖然不是每一支都會當, 但只要K數在5M以上的, 當機率就很高, 但我確信不是中毒, 目前我還查不到任何可能引發的問題, 而提出溢位問題, 確實有這個可能性, 但也無法查出是那一部份引發溢位, 所以根本無法改起! ===================引 用 RootKit 文 章=================== 為何不將 DLL 改為 BPL方式
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
蕭大俠那麼忙還抽空出來, 真不好意思, 我現在使用Euraklog是可以偵測到錯誤的, 但是發生在 End. 這裡, 也就是程式全段是沒有什麼問題, 在程式結束時才發生錯誤, 這應該是記憶體釋放出現問題, 但我自已創建的物件應該都沒有問題, 可能發生在第三方控件上, 但也不知是那組? 現在我的處理方式 1.在xp上會引發這個問題, 但在 win7 上就不會, 可能 win7 的防當機制處理的比較好 2.把檔案K數降低, 也可以解決(降低)這個問題 3.把檔案改成 EXE 的編譯, 也不會發生這個問題 所以我認為應該是 EXE CALL DLL 有一些動態管理上的問題 ===================引 用 aftcast 文 章=================== 太忙,快速插花! 把dll的source code 加入主程式的project group裡,這樣不是可以debug到dll的錯誤嗎? (我用cb的做法來想,不確定delphi,但理當同理?!) |
ANDY8C
資深會員 發表:114 回覆:582 積分:299 註冊:2006-10-29 發送簡訊給我 |
PD 的問題,也 曾困擾我... (AES加解密)
原用 DELPHI 2007 寫的,都沒問題,在 XE2 就無法回傳正確值 在後來聽網友建議,把它包成 DLL (DELPHI 2007) 在 XE2 去呼叫此 DLL ,結果回傳是錯的 所以 用 DLL 在換版本時,也不一定完全有效 最後只好在 XE2 下,,重寫一支 但很奇怪....相同的字串在 D2007 產生的結果,與 XE2 產生的不一樣, 但都可以還原原來的字串 所以有些問題,不一定想的那麼簡單,做了才知道.
------
--------------------------------------- 偶爾才來 KTOP ,交流條碼問題,在 FB [條碼標籤達人] 社團留言,感恩. |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
我覺得andy兄你的問題是該死的unicodestring造成的。
新版的字串有個特別功能---會自動(雞婆的)幫你轉字串的編碼,當你從某種字串,比如utf8,或ansi,或unicode中間若交換來交換去,甚至"沒理由的",就會把你的字串變到不成樣子。不過,若在同一個版本寫dll,可能會因為"錯的"進,也"錯的"出,所以也表現"正常"。當你用2007的dll時,因為若用了字串的功能,所以和新版肯定會不合。 dll不會有版本的問題--這句話原則上是對的。但有個前題: 不要使用任何字串(ansistring,shortstring…),只能用PChar"而且"要自己去alloc一個記憶體來放,簡單講就是用delphi的指標 自己配記憶體。而不能用現有的字串型別。如此dll就不會有問題。 同理,若是cb寫的dll,就是要用 char* 與 new/delete 記憶體來搞。也最好別用anistring等現有的來處理會最佳。 ===================引 用 ANDY8C 文 章=================== PD 的問題,也 曾困擾我... (AES加解密) 原用 DELPHI 2007 寫的,都沒問題,在 XE2 就無法回傳正確值 在後來聽網友建議,把它包成 DLL (DELPHI 2007) 在 XE2 去呼叫此 DLL ,結果回傳是錯的 所以 用 DLL 在換版本時,也不一定完全有效 最後只好在 XE2 下,,重寫一支 但很奇怪....相同的字串在 D2007 產生的結果,與 XE2 產生的不一樣, 但都可以還原原來的字串 所以有些問題,不一定想的那麼簡單,做了才知道.
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
pd兄,
聽你這樣描述後,我覺得你可以在 End.這個地方下中斷。然後使用trace into的方式,不能用trace over喔。用trace into追進去後,就會慢慢的經過整個解構的過程,於是就可以再深入了解是解到哪裡出問題。一步一步的trace into…直到爆了。然後看一下 call stack 的除錯窗。可以幫助知道是呼叫了哪個爆了。 若把dll的project,與主程式的project,都加入project group中,即該group中有二個project。這樣可以追到dll的source code上,可能會更明白問題。 xp會發生,win7不會發生。這種事我遇過一些。主要的原因是win7對於不正常的中止(但又不很嚴重)它會裝啞。但xp不會。所以,很肯定的是,一定是程式上有什麼寫過頭,或提早釋放,但又被再釋放之類的。 若元件有multithread的情形,則亦會有釋放過快,但thread沒結束又去讀等問題… 這樣的情形一定非要debug進去才會知道。光用眼看,很難! dll 釋放的順序也很重要! 以上請參考一下囉 ^^ ===================引 用 P.D. 文 章=================== 蕭大俠那麼忙還抽空出來, 真不好意思, 我現在使用Euraklog是可以偵測到錯誤的, 但是發生在 End. 這裡, 也就是程式全段是沒有什麼問題, 在程式結束時才發生錯誤, 這應該是記憶體釋放出現問題, 但我自已創建的物件應該都沒有問題, 可能發生在第三方控件上, 但也不知是那組? 現在我的處理方式 1.在xp上會引發這個問題, 但在 win7 上就不會, 可能 win7 的防當機制處理的比較好 2.把檔案K數降低, 也可以解決(降低)這個問題 3.把檔案改成 EXE 的編譯, 也不會發生這個問題 所以我認為應該是 EXE CALL DLL 有一些動態管理上的問題 ===================引 用 aftcast 文 章=================== 太忙,快速插花! 把dll的source code 加入主程式的project group裡,這樣不是可以debug到dll的錯誤嗎? (我用cb的做法來想,不確定delphi,但理當同理?!)
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
ANDY8C
資深會員 發表:114 回覆:582 積分:299 註冊:2006-10-29 發送簡訊給我 |
應該就是 AnsiString 與 WideString 的問題
大俠一出手,果然破解,小弟佩服.... 對了,吃飯聊是非的事,何時進行,安排在 xe3 那天嗎? ===================引 用 aftcast 文 章=================== 我覺得andy兄你的問題是該死的unicodestring造成的。 新版的字串有個特別功能---會自動(雞婆的)幫你轉字串的編碼,當你從某種字串,比如utf8,或ansi,或unicode中間若交換來交換去,甚至"沒理由的",就會把你的字串變到不成樣子。不過,若在同一個版本寫dll,可能會因為"錯的"進,也"錯的"出,所以也表現"正常"。當你用2007的dll時,因為若用了字串的功能,所以和新版肯定會不合。 dll不會有版本的問題--這句話原則上是對的。但有個前題: 不要使用任何字串(ansistring,shortstring…),只能用PChar"而且"要自己去alloc一個記憶體來放,簡單講就是用delphi的指標 自己配記憶體。而不能用現有的字串型別。如此dll就不會有問題。 同理,若是cb寫的dll,就是要用 char* 與 new/delete 記憶體來搞。也最好別用anistring等現有的來處理會最佳。 ===================引 用 ANDY8C 文 章=================== PD 的問題,也 曾困擾我... (AES加解密) 原用 DELPHI 2007 寫的,都沒問題,在 XE2 就無法回傳正確值 在後來聽網友建議,把它包成 DLL (DELPHI 2007) 在 XE2 去呼叫此 DLL ,結果回傳是錯的 所以 用 DLL 在換版本時,也不一定完全有效 最後只好在 XE2 下,,重寫一支 但很奇怪....相同的字串在 D2007 產生的結果,與 XE2 產生的不一樣, 但都可以還原原來的字串 所以有些問題,不一定想的那麼簡單,做了才知道.
------
--------------------------------------- 偶爾才來 KTOP ,交流條碼問題,在 FB [條碼標籤達人] 社團留言,感恩. |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
|
Coffee
版主 發表:31 回覆:878 積分:561 註冊:2006-11-15 發送簡訊給我 |
說到裝啞,我想到了SetErrorCode(0);(跑)
===================引 用 aftcast 文 章=================== pd兄, 聽你這樣描述後,我覺得你可以在 End.這個地方下中斷。然後使用trace into的方式,不能用trace over喔。用trace into追進去後,就會慢慢的經過整個解構的過程,於是就可以再深入了解是解到哪裡出問題。一步一步的trace into…直到爆了。然後看一下 call stack 的除錯窗。可以幫助知道是呼叫了哪個爆了。 若把dll的project,與主程式的project,都加入project group中,即該group中有二個project。這樣可以追到dll的source code上,可能會更明白問題。 xp會發生,win7不會發生。這種事我遇過一些。主要的原因是win7對於不正常的中止(但又不很嚴重)它會裝啞。但xp不會。所以,很肯定的是,一定是程式上有什麼寫過頭,或提早釋放,但又被再釋放之類的。 若元件有multithread的情形,則亦會有釋放過快,但thread沒結束又去讀等問題… 這樣的情形一定非要debug進去才會知道。光用眼看,很難! dll 釋放的順序也很重要! 以上請參考一下囉 ^^ ===================引 用 P.D. 文 章=================== 蕭大俠那麼忙還抽空出來, 真不好意思, 我現在使用Euraklog是可以偵測到錯誤的, 但是發生在 End. 這裡, 也就是程式全段是沒有什麼問題, 在程式結束時才發生錯誤, 這應該是記憶體釋放出現問題, 但我自已創建的物件應該都沒有問題, 可能發生在第三方控件上, 但也不知是那組? 現在我的處理方式 1.在xp上會引發這個問題, 但在 win7 上就不會, 可能 win7 的防當機制處理的比較好 2.把檔案K數降低, 也可以解決(降低)這個問題 3.把檔案改成 EXE 的編譯, 也不會發生這個問題 所以我認為應該是 EXE CALL DLL 有一些動態管理上的問題 ===================引 用 aftcast 文 章=================== 太忙,快速插花! 把dll的source code 加入主程式的project group裡,這樣不是可以debug到dll的錯誤嗎? (我用cb的做法來想,不確定delphi,但理當同理?!)
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。 為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。 在引述到我的文時自然會儘量替各位想辦法,謝謝大家! |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
最近比較忙, 所以晚一點再抽空按蕭大俠的做法試試看, 謝謝!
===================引 用 aftcast 文 章=================== pd兄, 聽你這樣描述後,我覺得你可以在 End.這個地方下中斷。然後使用trace into的方式,不能用trace over喔。用trace into追進去後,就會慢慢的經過整個解構的過程,於是就可以再深入了解是解到哪裡出問題。一步一步的trace into…直到爆了。然後看一下 call stack 的除錯窗。可以幫助知道是呼叫了哪個爆了。 若把dll的project,與主程式的project,都加入project group中,即該group中有二個project。這樣可以追到dll的source code上,可能會更明白問題。 xp會發生,win7不會發生。這種事我遇過一些。主要的原因是win7對於不正常的中止(但又不很嚴重)它會裝啞。但xp不會。所以,很肯定的是,一定是程式上有什麼寫過頭,或提早釋放,但又被再釋放之類的。 若元件有multithread的情形,則亦會有釋放過快,但thread沒結束又去讀等問題… 這樣的情形一定非要debug進去才會知道。光用眼看,很難! dll 釋放的順序也很重要! 以上請參考一下囉 ^^ |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |