全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2456
推到 Plurk!
推到 Facebook!

RegisterClasses/unRegisterClasses

尚未結案
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-16 08:48:51 IP:211.21.xxx.xxx 未訂閱
在 bpl 中我使用了RegisterClasses/unRegisterClasses 常常在主程式(EXE 檔)退出後出現 Access ...not read .... 的錯誤 應該是有 class 未被 unregister 但不知是否有函式可列出目前記憶體中的 class list ?
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-16 11:08:26 IP:219.80.xxx.xxx 未訂閱
你好:
  系統結束時,Delphi 會自行釋放所有以註冊的 Class
所以應該不是這個問題。有可能是你建立了某些元件,在釋
放前先執行了 UnLoadPackage 導致資源無法釋放。你可以做
一個新的專案與 Package 測試一下看看是否為相同的錯誤。    //Package1 內的物件宣告
  TTest = Class (TComponent)
  end;    var
  t1, t2 : TComponent;    // 主程式內的程式
procedure TForm1.Button1Click(Sender: TObject);
var
  TestClass : TComponentClass;
begin
  PkgHWND := LoadPackage ('Package1.bpl');
  if PkgHWND = 0 then system.Exit;      TestClass := TComponentClass (GetClass ('TTest'));
  if TestClass = nil then
    ShowMessage ('找不到物件')
  else begin
    ShowMessage ('測試開始');
    t1 := TestClass.Create (nil);  
    t2 := TestClass.Create (Self); 
    UnLoadPackage (PkgHWND);
  end;
end        t1 沒有指定 Owner,t2 的 Owner 是 Form1 在尚未釋放 t1 與 t2 前
就呼叫 UnLoadPackage 釋放 Package 會使兩個原本存在的記憶體空間不存
在,且 TComponent 的 RemoveComponent 機制也不會起作用(我不清楚會不會
造成 Leak),對 t1 當然無所謂,但 Form1 並不知道所管理的 t2 物件已
經消失,所以在 Form1 被 Free 時,才會造成釋放 t2 時產生 AV 的錯誤。    不擅言詞,贅述勿怪。給你參考,上述如有錯誤,也請先進們指正。    PS : 
    你可以先把 t2 給註解掉,執行程式與結束,不會有任何錯誤產生。
再把 t1註解掉,留下 t2 執行程式與結束將造成 AV 的錯誤。
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-16 22:37:57 IP:211.21.xxx.xxx 未訂閱
引言: .... 系統結束時,Delphi 會自行釋放所有以註冊的 Class 所以應該不是這個問題...
長官,這是否意味著根本不需要有 unRegisterClasses 這個指令 ? 我手上找到的資料 1.UnRegisterModuleClasses(ModuleInstance); //直接註銷 Package 2.UnloadPackage(ModuleInstance); //間接註銷 , 呼叫 Package 中 的 finalization 區段 根據我的測試,的確是因為有被 LoadPackage() 的 package 未被 UnloadPackage() , 主執行檔結束後就會出現 access ..not read...的錯誤 而 UnloadPackage 是呼叫 Package 中 的 finalization 區段 , 而我在 finalization 區段就是只有寫著 unRegisterClasses() , 未執行 UnloadPackage() 應該就是表示未 unRegisterClasses() 再討論吧 ... 發表人 - bruce0211 於 2004/09/16 22:44:32
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-16 23:30:23 IP:61.56.xxx.xxx 未訂閱
你好:
  你可以去追蹤 RegisterClass 這個函式,實際上 Class 的註冊程
序是藉著操作 RegGroups 這個私有變數來達成的,你再看看 Classes 
內的 finalization 區段,已經有做釋放的動作。我想有很多 Class 
是 Delphi 幫我們執行 Register 的,所以他會在程式結束時進行釋放
的工作,因此如果使用者 Register 而未 UnRegister 在程式最後都會
一併一起處理。至於你說那 UnRegisterClass 就不需要了,你可以看一
下 Help 文件中的最後一行這應該能說明為何需要 UnRegister 這的程序了。
"After unregistering a class, its name can be reused to register another object class."      如果再深入去了解 RegisterClass 所做的事(FClassList.Add(AClass)),
你會發現他是將 Metaclass 本身存放在一個 TList 中,這個說明了註冊
的動作僅是做一個紀錄,並沒有在系統取得任何資源(TList 自己用的不算喔),
舉例來說 TForm 的宣告也需要一些記憶體空間存放 VTable RTTI 等相關資訊,但因為
這是由 Delphi 管理的,因此自然不需要我們去擔心。但 TForm.Create (nil) 所實體
化的記憶體空間,就必須要由我們自行釋放(有 Owner 的就依任務需求而定囉)。我的意
思是 RegisterClass 所註冊的東西本來就是 Delphi 所管理的,在程式結束時會將這些
資源釋放掉。所以我覺得你的問題應該不是這兩個程序所造成的。    以上所言是我一點小小心得,如有錯誤,懇請先進指正。
    < src="http://sourceprovide.deepen.com.tw/K_Top/bp.gif">
        
系統時間:2024-05-07 16:54:35
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!