2008-12-10 125 views
3

我正在使用第三方DLL編寫的非託管C++來控制我們擁有的某些硬件。如何重新加載經常崩潰的第三方DLL

不幸的是,這個DLL不時崩潰,我的任務是讓它自動「重新加載」。我不太確定如何繼續獲得最佳結果。

我的項目使用C++。Net 2.0(2005)。我將第三方的東西封裝在單獨的DLL中。我一直在嘗試FreeLibrary()和LoadLibrary()。但是,當我FreeLibrary(),一些內部DLL依賴關係仍然分配和LoadLibrary()將使其崩潰,因爲內存損壞。

建議的另一種方法是使用.NET遠程接口重構整個項目。這會使殺死另一個進程並重啓它變得更容易,但這將是很多工作。

有什麼建議嗎?指針?提示?

回答

10

最有效的方法是根本不在應用程序的進程中加載​​該DLL。相反,創建第二個進程,其唯一的工作就是代表您的應用程序使用該DLL。您可以使用共享內存區域,本地套接字或其他IPC機制來控制代理進程。

這樣,當有問題的DLL崩潰時,您可以簡單地允許代理進程死掉,而不用擔心嘗試確保DLL不會破壞重要任務的(幾乎不可能的)任務。您的主進程只需要啓動一個代理進程的新實例並繼續。

4

我不是一個Windows專家,但我認爲一般的想法應該成立。

LoadLibrary,FreeLibrary處理將DLL映射到進程內存空間。你看到的腐敗大概是由於DLL內部的一些代碼做了「壞事」,幾乎肯定會破壞進程內存。現在,如果它崩潰了,幾乎可以肯定的是它殺死了正在運行的線程 - 如果不是整個過程。

我會採取一個有根據的猜測,可靠恢復和確保無損內存的唯一方法是運行犧牲進程作爲流氓DLL的包裝。我假設遠程接口是這樣做的一種方式。可能有其他人。

+0

對,對於本機代碼,你永遠不知道它損壞了哪些內存(結構) - 包括非常擁有的CLR。 – 2008-12-11 16:44:55

0

LoadLibrary和FreeLibrary是開始,但是如果你想能夠在DLL中發生崩潰,那麼你需要將所有調用包裝到SEH(結構化異常處理)__try/__catch塊中的DLL中。注:這與C++異常和try/catch塊完全不同。有關更多信息,請參閱MSDN。

0

如果DLL本身崩潰並且您的公司會爲此付出代價,那麼可能需要投入時間重新創建它。最好解決這個問題,而不是僅僅爲了解決問題。

+0

除非你打算進行逆向工程,否則這可能是不可行的。對於僅有軟件的DLL而言,這可能是一個合理的建議,但對於驅動程序來說這是不實際的。 – Draemon 2008-12-11 17:14:39