2017-02-17 22 views
2

我用P/Invoke調用來包裝本機API。對於錯誤處理,我使用以下方法:用P/Invoke提高託管和非託管回調鏈的異常

  • 從託管代碼中獲取回調函數。
  • 從非託管代碼調用此回調函數以指示錯誤。
  • 在回調中拋出異常。

換句話說流動是這樣的:

Managed Method => (P/Invoke) Unmanaged Function => Managed Callback => Throw Exception.

當我測試此方法我可以成功地捕獲該異常在所述第一管理方法。但是,我不能100%確定這不會對堆棧或泄漏內存造成任何副作用。

使用這種方法安全嗎?如果沒有,是否有任何其他方法來指示錯誤(可能包括堆棧跟蹤)而不使用P/Invoke混淆API?

P.S.我有權訪問本機代碼。

+0

託管回調的工作是什麼?如果存在的唯一原因是引發一個管理異常,那麼您應該考慮編寫一個C++/CLI互操作程序集,而不需要託管回調。 – IInspectable

+0

是的,我知道C++/CLI,但項目是以P/Invoke方法開始的,它需要一定量的工作來轉換現有的功能。 –

+0

您可以繼續使用P/Invoke,然後將混合模式互操作程序集用於新代碼。無論如何,這並沒有完全回答我所問的問題。 – IInspectable

回答

1

簡答:是的,它很安全。

在某些條件下:

  • 非託管函數可以處理SEH異常(C++可以,但C不能)
  • 託管函數將所述異常傳遞到它的調用者,所以它的調用者必須能夠理解並處理Managed異常(或將其傳遞給上層)。

例如,您無法啓動新線程並在新線程中調用託管回調,回調拋出的異常肯定會終止您的應用程序。

+0

通過新線程你是指本地線程,託管線程還是兩者兼而有之? –

+0

似乎第一個條件還應該包括只有Visual C++支持這一點。 –

+0

C++和C都可以處理SEH異常。兩者都不提供標準語言功能。除非編譯C++代碼並指示編譯器變爲非標準,並允許'catch(...)'處理SEH異常(編譯器開關'/ EHa')。 – IInspectable