麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Delphi > 正文

Delphi點滴

2019-11-18 18:25:42
字體:
來源:轉載
供稿:網友
 
 
用Delphi的過程中難免會遇到很多奇怪的問題,而Delphi的文檔也出奇的少,因此只能自己慢慢的總結,所以有了下文(由于只是零散的細節,所以文筆上沒有花什么功夫,可能會比較亂,但應該能夠理解;-))。
如果:
1. 你有下面問題的更好解決方法,請告訴我,和csdn上的朋友
2. 你有其他的問題,請列出問題,以及你的解答,告訴我,和csdn上的朋友。
 
溝通創造一切!

正文:
 
Q: 在Delphi的DLL中制作的Form,如果在Exe中ShowModal時,會在任務欄上出現兩個Icon,為什么?如何解決這個問題?
A: 下面是一種典型的DLL中放Form的方法:
DLL:
function ShowFrm: TModalResult; stdcall;
begin
Form1 := TForm1.Create(Nil);
try
Form1.ShowModal;
finally
Form1.Free;
end;
end;
主EXE:
function ShowFrm: TModalResult; stdcall; external 'TestDLL.dll';
 
 
begin
ShowFrm;
end.
 
以這種方式做出的DLL中的Form,會和主應用程序顯示另一個Icon,其原因在于:
Delphi中對于DLL會另外再創建一個application,而每個Application都會顯示一個任務欄的Icon。
解決方法:
在主應用程序中將主EXE的Application傳入DLL,如下:
DLL:
function ShowFrm(app: TApplication): TModalResult; stdcall;
var
oldApp: TApplication;
begin
oldApp := Application;
Application := app;
Form1 := TForm1.Create(Nil);
try
Form1.ShowModal;
finally
Form1.Free;
end;
Application := oldApp;
end;
主EXE:
function ShowFrm(app: TApplication): TModalResult; stdcall; external 'TestDLL.dll';
 
 
begin
ShowFrm(Application);
end.
注:DLL中的Application和EXE中的Application還是有些區別的,看Forms.pas中的代碼:
constructor TApplication.Create(AOwner: TComponent);
begin
if not IsLibrary then CreateHandle;
end;
可以知道,DLL中的Application沒有Handle,因此不會進行消息循環處理,這也是很正確的。
 
Q: Delphi中的DLL,經常出現問題!
A: 至所以出現問題,是因為Delphi本身的內存管理機制。比如:
在DLL中創建一個對象:
x := TClass.Create(Application);
這時,Delphi會在Application Free時自動Free x,但由于x是在DLL的地址空間中,當Application結束時,DLL的地址空間可能已經失效(不同的操作系統會有不一樣),因此這時對x的釋放操作就會引發異常。
又比如:
在EXE中創建了一個對象,并且傳入了DLL作為DLL中的局部變量,這樣在DLL銷毀時,由于Delphi會將所有超出作用域的變量自動釋放,因此如果再在EXE中使用這個對象,就會引發異常。
 
總的說,問題是由于“聰明”的Delphi編譯器的內存管理機制,和Windows的DLL加/卸載機制,導致了DLL和EXE中的內存存取沖突。
 
解決方法:(只要遵循以下幾個原則就可以避免大多數的問題)
1.在DLL和EXE之間,盡量不要使用Delphi的自動內存管理機制,由程序員自己對對象的生命期負責,比如:
對于上面的x := TClass.Create(Application);把它改成:
x := TClass.Create(nil);
這樣,Application就不會再Free它了。當然,程序員必須自己來釋放它。
2.盡量避免在DLL和EXE之間存在不同的指針指向的同一個對象。比如,在DLL中有x指向TClass對象,在EXE中又有y指向TClass對象,這樣在任何一邊的內存釋放都會導致另一邊的內存無效。
3.其他…
                                                                                                             
Q: 一個做周期性任務的線程,在其中需要暫停片刻,然后繼續運行,但如果這時需要讓線程停止(比如進程已經結束了),那該怎么辦?
A:
解決方法一:
在線程中通過Sleep進行周期循環。(如果在線程中通過Sleep暫停了,通過Resume等方法是無法使得線程重新復活的)
通過KillThread來結束線程。
這是最簡單的方法,但也太粗暴,可能會導致問題(KillThread是Windows不推薦使用的API)
 
解決方法二:
在線程中Suspend,在線程外面通過一個定時器,每隔一段時間就Resume。代碼如下:
// Thread
PRocedure Execute;
begin
while not Terminated do
begin
…   // 處理代碼
Suspend;
end;
end;
 
// 外面
// 定時器
procedure OnTimer(Sender: Tobject);
begin
thd.Resume;
end;
// 要結束線程的地方
thd.Resume;
thd.Terminate;
thd.WaitFor;                 // 一般在結束線程后得通過WaitFor確認線程已經真的結束了。
 
問題:線程和外部的耦合太強了,甚至線程的操作周期得通過外面的定時器來確定。
 
解決方法三(這是我想到的最好方法):
在線程中通過信號量進行暫停操作。
// Thread
TMyThread = class(TThread)
private
  Event: TEvent;
protected
  procedure Execute; override;
public
    constructor Create(loginInfo: TLoginInfo); overload;
    destructor Destroy; override;
    procedure SetEvent;
end;
 
{ TMyThread }
 
constructor TMyThread.Create(loginInfo: TLoginInfo);
begin
  Event := TEvent.Create(nil, True, True, 'EventName');
end;
 
destructor TMyThread.Destroy;
begin
  Event.Free;
  inherited;
end;
 
procedure TMyThread.Execute;
begin
  inherited;
  while not Terminated do
  begin
    // ...
    Event.ResetEvent;
    Event.WaitFor(10000);
  end;
end;
 
procedure TMyThread.SetEvent;
begin
  Event.SetEvent;
end;
 
對于需要中斷線程的程序,只需如下代碼即可:
begin
  …
 thd.Terminate;
 thd.SetEvent;
thd.WaitFor;
end;

上一篇:Delphi7的IDE概述(二)

下一篇:古都Delphi

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 免费黄色小网站 | 亚洲精品欧美二区三区中文字幕 | 精品少妇v888av | 国产正在播放 | 午夜视频大全 | 国产69精品久久久久久 | 久久国产成人午夜av浪潮 | 九色新网址 | 91精品国产福利尤物免费 | 精品在线一区二区三区 | 黄视频免费在线观看 | 久久国产免费视频 | 91av在线影院 | 日韩一级免费 | 欧美aⅴ视频 | 成年性羞羞视频免费观看 | 操操日日| 一区二区久久久久草草 | 欧美日穴视频 | 久久久婷婷一区二区三区不卡 | 国产一区二区视频在线播放 | 中文字幕综合在线观看 | 欧美激情性色生活片在线观看 | 亚洲精品一区二区三区免 | 黄色香蕉视频 | 久久国语对白 | 成人免费观看49www在线观看 | 中文字幕国产欧美 | 久久久久久久一区二区 | 最新在线黄色网址 | 男女做性免费网站 | 成人在线视频免费播放 | 91精品国产一区二区在线观看 | 日本在线视频二区 | 史上最强炼体老祖动漫在线观看 | 欧美一区二区三区久久精品视 | 国产成人高潮免费观看精品 | 免费观看黄色一级视频 | 欧美成人综合视频 | 欧美黄色性生活视频 | 中文字幕欧美一区二区三区 |