मैं मिनजीडब्ल्यू डेवलपर नहीं हूं, लेकिन आपका प्रश्न बहुत आम है और वास्तव में आप डीएलएल कैसे बनाते हैं इस पर निर्भर नहीं है। DLL देरी लोडिंग के
उपयोग (आवेदन की स्थापना के दौरान)
- DLLs
- DLLs और exe बंधन का अनूठा आधार पतों की चयन: इस तरह की समस्याएं आम तौर पर तीन तकनीक के उपयोग के साथ हल से होगा तकनीक
- एक छोटे से
DllMain
सटीक एस के DLL_PROCESS_ATTACH
भाग के अंदर DisableThreadLibraryCalls की कॉल में सुधार लोडिंग समय लिंकर या अन्य टूल्स का चुड़ैल जो आप उपयोग कर सकते हैं अपने विकास पर्यावरण पर निर्भर करते हैं।
समस्या को समझने के लिए आपको पता होना चाहिए कि निष्पादन योग्य या डीएलएल कैसे लोड किया जाएगा। सबसे पहले EXE या DLL स्मृति में मैप किया जाएगा। Memory mapped file (सेक्शन) बनाया जाएगा जो EXE/DLL को इंगित करता है। तो आपके पास प्रक्रिया में कुछ पते होंगे जो एक्सेस EXE/DLL फ़ाइल के अनुरूप होंगे। यदि आप डीएलएल को लिंक करते हैं तो आप मूल पता चुन सकते हैं। यदि पता पता स्थान में पते का उपयोग नहीं किया गया है तो कुछ भी नहीं किया जाएगा। यदि कोड की पहली पंक्ति का उपयोग किया जाएगा (आप डीएलएल से कुछ फ़ंक्शन कॉल करते हैं) तो प्रयुक्त पते के पास मेमोरी 8K का पृष्ठ फ़ाइल से स्मृति में लोड किया जाएगा। यदि दो प्रक्रियाएं एक ही डीएलएल का उपयोग करती हैं तो कोड के लिए भौतिक स्मृति प्रक्रियाओं के बीच साझा की जाएगी। यहां तक कि यदि आप प्रारंभिक चर रखते हैं तो वेरिएबल वाले पेज को चर के पहले परिवर्तन तक साझा किया जाएगा। संशोधन पर प्रक्रिया के लिए स्मृति के पृष्ठ की प्रतिलिपि बनाई जाएगी जिसने संशोधन किया था।
प्रक्रिया में डीएलएल लोड होने के बाद कॉलर के कुछ छोटे हिस्सों (उदाहरण के लिए EXE) को डीएलएल से उपयोग किए गए कार्यों के वास्तविक पते को शामिल करने के लिए संशोधित किया जाना चाहिए। डीएलएल के साथ ऐसा ही किया जाएगा जो किसी अन्य डीएलएल से कार्यों का उपयोग करता है।
सब कुछ सही ध्वनि, लेकिन आप DLL संकलन के दौरान किसी भी लिंकर विकल्प सेट नहीं है (यदि आप --image-base
या --enable-auto-image-base
लिंकर विकल्प का उपयोग नहीं करते हैं) आप के लिए डिफ़ॉल्ट मान एक ही आधार पते के साथ अपने सभी DLLs होगा (लिंकर)। तो पहले डीएलएल पते पर लोड किया जा सकता है। दूसरे डीएलएल को लोड करने के दौरान जो (या कुछ ओवरलैप्ड एड्रेस) से जुड़े होते हैं, डीएलएल का स्थानांतरण किया जाएगा। स्थानांतरण के दौरान डीएलएल सिल्ल का कोड संशोधित किया जाएगा और इसलिए 1) डीएलएल की लोडिंग धीरे-धीरे 2 होगी) कोड की संशोधित प्रति प्रक्रिया में बनाई जाएगी (जिसमें डीएलएल द्वारा उपयोग की जाने वाली मेमोरी शामिल है) 3) संशोधित प्रति डीएलएल के कई उदाहरणों के बीच साझा नहीं किया जाएगा (भले ही सभी उदाहरण एक ही तरीके से संशोधित किए जाएंगे)।
उदाहरण के लिए मैं आपको सबसे पहले Process Explorer का उपयोग करने की सलाह देता हूं ताकि यह सत्यापित किया जा सके कि आपके आवेदन में कौन से डीएलएल स्थानांतरित किए जाएंगे। आपको "व्यू"/"लोअर पेन व्यू" मेनू में "डीएलएल" विकल्प चुनना चाहिए और "विकल्प" मेनू के "हाइलाइटिंग कॉन्फ़िगर करें" में "रिलायंस डीएलएल" चेकबॉक्स का चयन करना चाहिए। आप अतिरिक्त रूप से अनुकूलित कर सकते हैं कि प्रत्येक डीएलएल के बारे में कौन सी जानकारी प्रदर्शित की जाएगी। आप नीचे दिए गए की तरह अधिक जानकारी अधिक धीमी गति से कार्यक्रम लोड किया जाएगा देखेंगे और अधिक पता स्थान आपके आवेदन के उदाहरण के बीच या जो एक ही DLL का उपयोग विभिन्न अनुप्रयोगों के बीच साझा नहीं किया जाएगा:
में उपरोक्त उदाहरण में आप देखते हैं कि पेड़ लेनोवो डीएलएल TPOSDSVC.dll
, HKVOLKEY.dll
और TPLHMM.dll
समान आधार पते 0x10000000
से जुड़े हुए हैं और केवल एक डीएलएल (TPOSDSVC.dll
) पते पर लोड किया जाएगा। दो अन्य डीएलएल को फिर से स्थानांतरित करना होगा।
मैं इस विषय के बारे में यहां एक पुस्तक नहीं लिख सकता। मैं आपको स्थानांतरण आवेदन पर अपने आवेदन की जांच करने की सलाह देता हूं। आप या तो लिंकर विकल्प (--image-base
या --enable-auto-image-base
का उपयोग कर सकते हैं जो आपको चाहिए) का उपयोग कर सकते हैं। पीई छवि की जांच के लिए आप dumpbin.exe टूल (विजुअल स्टूडियो से भी मुफ्त संस्करण में) का उपयोग कर सकते हैं।
अपने सभी DLLs के बाद आप EXE और उसके आश्रित DLLs के लिए अपने DLLs बाध्य करने के लिए विकल्प -u
साथ एक और उपकरण bind.exe
उपयोग कर सकते हैं अद्वितीय आधार पता होगा। यह अतिरिक्त रूप से स्मृति आकार को कम करेगा और एप्लिकेशन के प्रारंभिक समय में सुधार करेगा। यह आपके डीएलएल और EXE के IMAGE_DIRECTORY_ENTRY_IMPORT
और IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
अपडेट करेगा (the answer देखें)। Bind.exe
आंतरिक रूप से BindImageEx
एपीआई का उपयोग करता है। कई विंडोज इंस्टालर सेटअप EXE और DLLs के इंस्टॉलेशन के अंत में बाध्यकारी बनाने के लिए BindImage एक्शन और BindImage तालिका का उपयोग करते हैं।
डीएलएल और EXE के आकार को कम करने के लिए आप अन्य तकनीकों (here देखें) पर विचार कर सकते हैं।
मुझे नहीं पता कि आप मिनजीडब्ल्यू में देरी-लोड तकनीक का उपयोग कैसे कर सकते हैं, लेकिन यह निश्चित रूप से संभव होना चाहिए। विजुअल स्टूडियो आपको दो चरणों को करने की आवश्यकता है: Delayimp.lib
अतिरिक्त लाइब्रेरी के रूप में शामिल करें और /DELAYLOAD
विकल्प (here देखें) निर्दिष्ट करने के लिए कि डीएलएल से सीधे उपयोग के पहले उपयोग पर लोड किया जाना चाहिए। बहुत उपयोगी टूल Dependency Walker का उपयोग करके आप देख सकते हैं कि अधिकांश मानक माइक्रोसॉफ्ट डीएलएल तकनीक का उपयोग करते हैं। यदि आप तकनीक का उपयोग भी करेंगे तो आप अपने आवेदन के प्रारंभ समय में सुधार कर सकते हैं और उपयोग की गई स्मृति को कम कर सकते हैं।
यह संभवतः लोडिंग-इन-मेमोरी नहीं है, लेकिन डीएलएल के अंदर प्रारंभिक तर्क, जो इतना लंबा समय ले रहा है। स्मृति में डीएलएल को रखना प्रारंभिक विलंब से बच नहीं पाएगा। –
यह सच होने पर दुर्भाग्यपूर्ण होगा। मुझे लगता है कि स्रोत कोड तक पहुंच के बिना मैं कुछ भी नहीं कर सकता हूं? – SharpHawk
आप इसे आउट-ऑफ-प्रोसेस आरपीसी सर्वर में लपेट सकते हैं, लेकिन यह इसका उपयोग कर अक्षमता के लिए तेज़ पुनः कनेक्शन का व्यापार करता है। –