2015-09-05 24 views
0

我剛剛發現我可以卸載DLL隱式鏈接函數FreeLibrary()在C#中。我記得我不能在C++中做到這一點,但它在我的簡單測試項目中運行良好。我想知道這在我的真實項目中是否會好起來。 使用這種方法安全嗎?隱式鏈接和FreeLibrary在C#

回答

2

相當含糊,我不得不假設你談論通過pinvoke加載的DLL。是的,對FreeLibrary()的調用沒有任何保護。在C++中工作,以及顯式加載的DLL。不適用於隱式加載的DLL,它們會得到「無窮大」的引用計數。

pinvoke編組器在引擎蓋下使用LoadLibrary(),當第一個[DllImport]函數被執行時發生。 OS加載器只是保持一個引用計數,每個LoadLibrary()調用都會增加它並且FreeLibrary()會遞減。當它達到0時,它將被卸載。所以,如果你自己調用LoadLibrary()並調用FreeLibrary()兩次,那麼DLL 確實會卸載。映射DLL中代碼的內存映射文件以前使用的虛擬地址空間被釋放,並可以在隨後的分配中再次使用。

安全,不,這不是一個跳躍的想法。當你意外地在DLL中調用入口點時,你的程序將表現得很差。 pinvoke marshaller對此無能爲力,本地方法的存根已經生成。 AccessViolationException的賠率是體面的,但不能保證。任意代碼執行在技術上是可行的。

唯一真正安全的方法是確保包含pinvoke代碼的AppDomain被卸載。你沒有得到任何幫助,只有你必須實現自己的規則。

+0

非常感謝你的回覆。 但我的意思是關於隱式鏈接,而你在談論顯式鏈接。在C++中,FreeLibrary()只能在鏈接到函數LoadLibrary()的顯式鏈接上正常工作。另一方面,FreeLibrary()適用於C#中的顯式和隱式鏈接。我測試了幾次,並且希望確保爲隱式鏈接調用FreeLibrary()將來可能不會導致任何問題,因爲我找不到任何關於此的文檔。無論如何,感謝您提供的信息豐富的建議! – Jenix

+0

它沒有什麼不同,在C++中,您仍然可以調用LoadLibrary()一次和FreeLibrary()兩次來卸載隱式加載的DLL。如何將DLL隱式加載到C#程序中並不清楚你的問題。請改善它。請記住,.NET程序集不會由LoadLibrary或隱式鏈接加載,只能通過銷燬AppDomain來卸載。 –

+0

'在C++中調用LoadLibrary()一次和FreeLibrary()兩次'爲你工作?我已經嘗試過,稱爲FreeLibrary()超過10次,但對於使用'#pragma comment(lib,「myDLL」)'加載的DLL無效。無論如何,我會嘗試。在C#中,我使用DllImport屬性來加載自己的DLL,但問題是,無法爲此方法卸載。我搜索瞭如何卸載,但許多人說只使用LoadLibrary()和FreeLibrary()而不是DllImport。坦率地說,我看到一個人說像C++一樣在C#中調用LoadLibrary()和FreeLibrary()兩次。 – Jenix