2012-04-04 17 views
10

के साथ अनलोड नहीं करता है मेरे पास एक सी # प्लगइन है जो एक अलग सी ++ डीएलएल का उपयोग करता है। उस डीएलएल का एकमात्र संदर्भ प्लगइन के भीतर ही है। अभिभावक एप्लिकेशन सभी प्लगइन को अपने स्वयं के ऐपडोमेन में लोड करता है और प्लगइन अनलोड होने पर इस ऐपडोमेन को अनलोड करता है।सी ++ डीएलएल ऐपडोमेन

मैंने जांच की है, और जब मैं प्लगइन को अनलोड करता हूं तो मुझे निश्चित रूप से एप्लिकेशन की मेमोरी ड्रॉप दिखाई देती है। मैं लोड की गई सभी प्रबंधित असेंबली को भी हटाने में सक्षम हूं। समस्या यह है कि जब मैं देशी डीएलएल को हटाने की कोशिश करता हूं, तब तक जब तक मैं पूरा एप्लिकेशन बंद नहीं करता तब तक एक्सेस अस्वीकृत हो जाता है।

मैं इसे थोड़ी देर के लिए देख रहा हूं, लेकिन मुझे अभी भी पता नहीं चल रहा है कि यह डीएलएल स्मृति में क्यों रहता है।

उत्तर

18

ऐपडोमेन एक शुद्ध प्रबंधित कोड निर्माण हैं। ऐसा कुछ भी मूल कोड में मौजूद नहीं है, न ही विंडोज़ के बारे में कोई विचार है। तो एक लोड देशी देशी डीएलएल के लिए दायरा प्रक्रिया है। तकनीकी रूप से, पिनवोक मार्शलर डीएलएल की गिनती का संदर्भ दे सकता है और ट्रैक को ठीक से रख सकता है जो ऐप्पडोमेन ने डीएलएल के भार को ट्रिगर किया था। हालांकि यह नहीं बता सकता कि क्या कोई मूल कोड चल रहा है जो डीएलएल का उपयोग करता है। मूल कोड जिसे कोड से बनाए गए कॉल द्वारा में ऐपडोमेन, संभावित रूप से अप्रत्यक्ष रूप से एक मार्शल प्रतिनिधि के माध्यम से शुरू किया जा सकता है।

स्पष्ट रूप से आपदा तब होती है जब ऐपडोमेन मैनेजर एक डीएलएल को उतारता है जो कि इस तरह उपयोग किया जाता है, यह AccessViolation का निदान करने के लिए एक बुरा और असंभव है। विशेष रूप से बुरा है क्योंकि ऐपडोमेन को उतारने के बाद यह लंबे समय तक ट्रिगर कर सकता है।

तो मार्शलर उस तरह की गिनती को लागू नहीं करता है, डीएलएल लोड रहता है। केवल आप ही गारंटी प्रदान कर सकते हैं कि ऐसा नहीं हो सकता है, आपके पास डीएलएल में कौन सा कोड चलता है और यह कैसे शुरू होता है, इस पर आपके कुछ नियंत्रण हैं। आप DLL को अनलोड करने के लिए मजबूर कर सकते हैं लेकिन इसे एक हैक की आवश्यकता है। पिनवोक लोड लाइब्रेरी() खुद को डीएलएल को संभालने के लिए। और पिनवोक फ्री लाइब्रेरी() दो बार जबरन इसे अनलोड करने के लिए। न तो विंडोज़ और न ही सीएलआर देख सकता है कि आप धोखा दे रहे हैं। आप सुनिश्चित करना चाहिए कि इसके बाद डीएलएल का उपयोग नहीं किया जा सके।

+3

+1 अच्छा हैक :-) – Yahia

+0

अरे, बस बहुत स्पष्ट उत्तर के लिए धन्यवाद कहना चाहता था! – user472875

5

AFAIK (हुड के नीचे) देशी DLLs Win32 एपीआई LoadLibrary ... जो उन्हें प्रक्रिया स्मृति में सीधे लोड करता है के माध्यम से लोड करने के लिए की जरूरत है - एक .NET आवेदन के मामले में है कि करने के लिए एक AppDomain ... LoadLibrary विशिष्ट नहीं है AppDomain के बारे में बिल्कुल कुछ भी नहीं जानता है (जो विशुद्ध रूप से नेट-विशिष्ट होता है) ... इस प्रकार AppDomain उतारने जरूरी देशी DLLs उतारना नहीं है ... इस स्थिति के बारे में

विचार विमर्श दिलचस्प:

आप संबंधित प्लगइन के कार्यान्वयन को बदल सकते हैं, तो आप लागू करेगा "देर देशी बाइंडिंग" जो समस्या आप देख हल होगा:

संबंधित मुद्दे