2010-11-17 70 views
7

我正在用C編寫跨平臺共享庫(在linux中爲.so,在windows中爲.dll)。當前存在錯誤時,庫函數返回適當的錯誤代碼並寫入錯誤信息進入stderr。庫函數還會向stdout發送一些信息和調試消息。這適用於基於控制檯的客戶端。錯誤處理共享庫中的策略 - C

現在這個庫將有客戶端程序使用GUI編程使用C++ & wxWidgets。我想知道處理錯誤和通知它的最佳做法是什麼?在所有平臺上,UI應用程序能否訪問數據到stdoutstderr

我在想的另一種方法是庫初始化函數初始化一個將有函數指針的結構。庫中的所有函數都將採用此結構的實例並調用函數指針。這樣客戶可以選擇在哪裏打印郵件。

我想知道什麼是明顯的方法來解決這個問題?任何幫助都會很棒。

回答

14

最佳實踐(恕我直言)是爲圖書館不打印任何標準錯誤(或標準輸出),因爲他們甚至可能不存在。除了GUI情況之外,您還有一個服務器應用程序的用例,它沒有「控制檯」,並且可能希望使用像syslog()這樣的函數記錄錯誤。

一些方法用於處理錯誤信息,而無需直接打印出來:

  • 返回一個數字錯誤代碼,以及用於將其轉換成字符串

  • 返回一個struct /對象錯誤代碼提供的功能,其中包含附加信息

  • 在「會話」對象上提供返回有關最後一個錯誤信息的功能

  • 允許呼叫者寄存器在一個錯誤的情況下調用的回調

的一個例外「不寫從圖書館到標準錯誤」規則,我和合理舒適如果庫有一個「調試模式」參數,可以將詳細信息記錄到stderr。

10

一般而言,您不應該從您的庫中根本寫入stdout - 即使在可能破壞應用程序正在生成的輸出的控制檯應用程序中。 stderr有點可以原諒,但是除非應用程序請求它,否則你仍然不應該使用它。

OpenSSL是一個跨平臺的共享庫,它有很多相同的問題需要解決。他們的方法在內部錯誤隊列中有庫記錄詳細的錯誤信息,應用程序可以在看到錯誤返回值時請求這些錯誤信息,然後以適當的方式呈現給用戶。 (它還提供了將整個錯誤隊列轉儲到FILE *的便利功能)。

+0

還有一個問題。所以在OpenSSL中,內部錯誤隊列如何被清除? – 2010-11-18 04:23:57

+0

@Appu:爲應用程序提供了一個請求「下一個錯誤」的功能。這將從內部隊列中刪除最早的錯誤,並將其返回給應用程序。 – caf 2010-11-18 05:02:26

1

在Linux上,您應該使用rsyslog來記錄錯誤,而不是在標準輸出(或標準錯誤)上打印錯誤。既然你正在處理圖形用戶界面,也許你也可以彈出一個消息框(並非總是)。

我不知道窗戶,但我認爲它有類似的東西。

2

對於日誌消息,您應該允許客戶端向庫提供回調函數,以便客戶端可以決定如何處理它們,例如,發送到系統日誌或顯示在屏幕上的一個窗口中。

對於返回錯誤,你有三個基本策略:

  1. 返回一個錯誤代碼,並有將其轉換爲一個消息
  2. 函數傳遞一個指向對象,將保存錯誤指針參數消息信息
  3. 讓一些全局庫對象包含來自上次操作的錯誤信息。

不管你做什麼,你都不想只記錄錯誤信息,因爲客戶端可能想對它做些什麼。例如出現一個對話框。

我大概會跟2一起去。