2013-07-31 70 views
1

我已經創建了一個C++ DLL,並且正在C#應用程序中使用它。我應該如何報告錯誤?
使用異常和throw我的錯誤,或打印他們在std :: cout或std :: cerr,或其他?如果我在DLL中發出異常,我的C#應用​​程序是否能夠捕獲它?
什麼是這方面的最佳行動方案?我應該如何處理基於C++的dll中的錯誤?

+1

「C++ dll」是什麼意思?你是否使用'extern'或類似的方式公開本地類?通常DLL應該是「C DLL」(可能用C++編寫)或「COM DLL」或「託管裝配」。創建直接公開本機C++對象的DLL通常是一個壞主意,因爲如果沒有生成它的確切編譯器版本,很難鏈接。 – 2013-07-31 16:48:07

+0

答案很大程度上取決於您的C++代碼是否管理。 –

+0

是的,我使用了extern C,而我的C++沒有管理。 – Breeze

回答

1

下面是使用PInvoke調用一個拋出std::exception的方法的C#示例輸出。

ex = System.Runtime.InteropServices.SEHException (0x80004005): 
External component has thrown an exception. 
    at ConsoleTester.Program.throw_exception() 
    at ConsoleTester.Program.Main(String[] args) in ConsoleTester.cs:line 18 

注:在這種情況下throw_exception()是暴露的本地方法,並將其稱爲子方法,但你不能看到堆棧跟蹤的一部分。所有你得到最深的堆棧幀是本地邊界。

所以,它不是完美的,但它確實有效。返回錯誤代碼可能是處理這個問題的最爲標準的方式,但如果您是該庫的唯一使用者,則可能不會有太大的區別。

注意:stdin/stdout通常是處理錯誤的最糟糕的方法。例外情況是編寫自定義錯誤處理對象或一組例程以避免出現錯誤時應用程序中的所有內容都可以訪問。 (這種接口的輸出有時可能是標準輸入/標準輸出或文件或任何有用的配置)認爲log4j或log4net在這裏...

通常,日誌記錄只是錯誤處理的一部分。您仍然需要嚮應用程序的其他部分發出信號,以對不利條件做出反應並(希望)從其中恢復。在這裏,只有錯誤代碼或異常真的起作用(並且反正主程序流程中的異常會被最小化)。

1

請勿在stdoutstderr上打印錯誤!您需要以編程方式返回錯誤,以便C#應用程序有機會處理它們。如果主機應用程序是一個GUI應用程序呢?

從C++ DLL中拋出異常充滿了危險。即使您的應用程序是C++,也必須使用與DLL完全相同的編譯器進行編譯,如@ebyrob所述。從C#調用,我不確定。

最佳的操作過程是返回錯誤代碼。

1

這真的取決於錯誤的強度。我見過的大多數庫都會從其函數調用中返回成功或失敗結果值,您可以在代碼中使用它時手動檢查結果值。他們通常會提供另一種方法,只是在您想要查看時才檢索錯誤消息。

爲真正的大事保留拋出異常,你不能繼續沒有,這將迫使人們使用你的庫來修復這些錯誤(或者至少,看到有一個大問題)。

我不會推薦在控制檯窗口中打印任何東西,這是一個非常緩慢的操作,並且在那裏強制任何人使用你的庫來獲得這些開銷,而沒有什麼優化選擇。如果他們想打印錯誤消息,他們可以從庫中檢索錯誤數據並將它們自行打印出來。

相關問題