由于要與別的軟體集成,需要撰寫一個用于通信的dll,封裝TdTCPServer的時候不回應onExecute事件和ondisconect事件,但是onConnect事件可以回應。應該是執行緒問題,怎么解決?
uj5u.com熱心網友回復:
既然寫Dll,干嘛還用控制元件,直接socketuj5u.com熱心網友回復:
dll中不要使用vcl,到時你就知道痛苦了。要不你就用包bpl。uj5u.com熱心網友回復:
自己封裝socket太麻煩了,時間上來不及了,偷個懶。因為這個dll是給別的軟體(不是delphi寫的)集成用的,不能打成bpl。原因好像是dll中沒有主執行緒,而事件相應是通過主執行緒來呼叫的,所以沒有反映了。。
uj5u.com熱心網友回復:
不解uj5u.com熱心網友回復:
DLL中傳遞Delphi物件是很啰嗦的,盡量不要使用類
uj5u.com熱心網友回復:
恩,可以用介面實作uj5u.com熱心網友回復:
倒不是啰嗦,主要還是delphi對于記憶體的管理方式。可以看看那本《delphi in a nutshell》,中文好像叫《delphi 開發指南》。我引兩段:
使用DLL時,必須主要動態記憶體。任何由DLL分配的記憶體應該DLL被卸載后都將釋放。但是,你的應用程式可能保留有指向那塊記憶體的指標,如果不注意的話,它可能導致存取障礙或更糟糕的問題,最簡單的解決辦法是把ShareMem單元作為第一個單元在你的應用程式和它加載的每一個庫里面使用。ShareMem單元把所有的記憶體請求重新指向一個單獨的DLL(BorlndMM.dll),當應用程式運行時它一直被加載,你可以加載或者卸載DLL,而不必擔心會把指標懸掛起來。
......
ShareMem 解決了一種記憶體問題,但解決不了另一種:類標識(classidentity)。 如果在應用程式和DLL中使用了類A,Delphi不能判斷出兩個模塊使用的是同一個類。雖然兩個模塊使用相同的類名稱,但這并不意味著這兩個類是相同的。Delphi遵循最安全的路線,假定這兩個類是不相同的,即使你知道得更多,但你也沒有簡單的辦法來告訴Delphi。
有時,具有不同的類標識并不會引起任何問題,但如果你的程式試圖越過一個DLL的邊界來使用一個物件的參考,則is和as運算子將不會按照你期望的方式作業,因為DLL認為類A與應用程式的類A不同,is運算子將永遠回傳False。
一個避免該問題的辦法是不越過DLL的邊界傳遞物件。例如,你有一個圖形物件,但不要傳遞一個TBitmap物件,而是傳遞一個Windows句柄(HBITMAP)來代替。另一個解決辦法就是使用包。
......
如果使用DLL并試圖在DLL之間或者在應用程式與DLL之間傳遞物件,那么你將會遇到一系列的問題。首先,每一個DLL和EXE都保持著其本身對類表的拷貝。對于在DLL和EXE之間傳遞的物件來說,is和as運算子將不能正確地作業。使用包可以解決這一問題。另一個問題是在DLL中分配的記憶體都歸該DLL所有。當Windows卸載該DLL時,所有由這個DLL分配的記憶體都被釋放,即使EXE或另一個DLL保留著指向該記憶體的一個指標亦是如此。在使用字串、動態陣列和Variant時,這將會成為一個主要的問題,因為你永遠不知道Delphi什么時候會自動分配記憶體。
解決辦法是將ShareMem單元作為你的工程和每一個DLL的第一個單元。ShareMem單元安裝一個記憶體管理器來重新指向所有對一個特殊DLL--BorlndMM.dll的記憶體分配請求。應用程式并不卸載BorlndMM,直到它退出為止。這種DLL魔術是公開進行的,所以你不用擔心其細節。只要保證使用ShareMem單元,并保證它是程式和庫使用的第一個單元即可。當你向客戶或消費者發布你的應用程式時,需要將BorlndMM.dll包括進去。
uj5u.com熱心網友回復:
用介面吧,應該可以滿足你的要求。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/137993.html
標籤:網絡通信/分布式開發
上一篇:請教如何獲得聯想主板的主板資訊?
