2010-02-12 97 views
4

在Delphi中處理DLL中的異常的正確方法是什麼?Delphi中的異常和DLL

像這樣

on E : ESomeException do ... 

if (E is ESomeException) then ... 

失敗,因爲DLL和主應用程序的單獨的類型登記處。

+0

你應該仔細研究如何恰當地懲罰DLL的作者。希望能及時解決所有用戶的問題。 – mghie 2010-02-12 11:57:29

+1

如果您碰巧有一個鏈接描述了DLL中錯誤處理的最佳實踐,請發佈。 – jpfollenius 2010-02-12 12:21:11

+4

我不知道一篇文章,但它確實很簡單。如果你想使用異常,寫一個BPL,並將你的程序綁定到同一個Delphi版本。如果你不想這樣做,並且你編寫了一個DLL,那麼不要假定主機環境的任何事情,所以異常不能跨越模塊。在每個導出的函數中都有一個頂級異常處理程序,並返回錯誤代碼,就像COM一樣。查看'OleCheck()'來查看錯誤代碼引發異常的例子。注意:有關於對象共享的SO討論也類似。但最終必須遵守編寫DLL的規則。 – mghie 2010-02-12 13:12:09

回答

8

對於純DLL的異常不允許穿越DLL邊界(如Deltics提及) - 無論使用哪種語言。

你得到了all sorts of trouble there,特別是因爲你不知道哪種語言,RTL,內存管理器等位於邊界的每一邊。

所以你又回到了經典的錯誤處理範例:

而不是DLL的,你可以使用BPL軟件包(建議使用Lars):您知道雙方將使用相同的RTL和內存管理器。

無論如何,包和BPL通常都會給你一個版本化的噩夢(太多的自由度)。

更嚴格的解決方案是去一個單一的可執行文件;這解決了兩個問題:

  • 容易得多版本
  • 保證只有一個RTL和內存管理器

--jeroen

PS:我做了這個額外的答案,因爲它允許更容易粘貼鏈接。

5

最安全的方法是首先不允許異常從DLL「逃脫」。

但是,如果你有超過DLL的來源沒有控制權,因此無法確保這一點,你仍然可以測試異常類名:

if SameText(E.ClassName, 'ESomeException') then ... 
+0

這就是我現在使用的解決方法。不幸的是,它不允許捕獲父級異常類。什麼是在DLL中進行錯誤處理的正確方法?錯誤代碼? – jpfollenius 2010-02-12 08:01:54

3

如果使用運行時包(至少rtlxx.bpl )爲您的應用程序和您的DLL,然後都具有相同的類型,它將工作。當然,這限制了你的DLL的使用只適用於Delphi/BCB。

另一個解決方案是不使用例外,就像Deltics的建議。返回錯誤代碼。

或者使用COM。然後,你可以有例外,而不是隻限於你的DLL。

+0

謝謝!不幸的是運行時軟件包不適合我們。 COM對我來說太過矯枉過正了。這種情況下的異常究竟有什麼問題(除了動態類型檢查不起作用外)? – jpfollenius 2010-02-12 08:25:19

+1

....僅限於BCB/Delphi的特定版本。 (D2006/D2007可能例外) – 2010-02-12 08:29:24

+0

爲什麼運行時軟件包不是一個選項?使用SimpleShareMem,您已經與特定的Delphi/BCB版本綁定。而只是使用rtl70.bpl作爲運行時包,只會給你一個額外的DLL分發。 – 2010-02-12 15:50:01

-2

此解決方案似乎爲我做的:

function ExceptionMatch (Exc : Exception; ExcClass : TClass) : Boolean; 

var 
    CurrClass   : TClass; 

    begin 
    CurrClass := Exc.ClassType; 
    while (CurrClass <> nil) do 
    begin 
    if SameText (CurrClass.ClassName, ExcClass.ClassName) then 
     Exit (True); 
    CurrClass := CurrClass.ClassParent; 
    end; 
    Result := False; 
    end; 

我願意爲你破壞這個:)

有什麼不對的這種做法?什麼是潛在的危險?

+0

內存管理,RTL版本控制,bounary兩端不存在的類。而這只是你惡夢的開始...... – 2010-02-12 10:51:30

+0

我使用'SimpleShareMem',所以內存管理在這裏不成問題。我不明白你的其他觀點。 – jpfollenius 2010-02-12 10:59:04

+2

順便說一句:你downvote這和updvote Deltics(好)的答案?我使用與他所建議的相同的方法,我無法影響DLL本身。 – jpfollenius 2010-02-12 11:05:53